Esempio n. 1
0
void CDM_FEA::CalcA() //populate "a" matrix!
{
	for(int b=0; b<NumBonds; b++){ //for each bond!
		MakeBond(a, b);
	}
}
Esempio n. 2
0
void CDM_FEA::CalcForces() //fills in forces, reaction forces, and strains!!!
{
	for (int i=0; i<DOF; i++){ //set all to zero force
		F[i] = 0;
		e[i] = 0; //internal strains
		b[i] = 0; //do reactions here.... (if we want)
	}
	for (int i=0; i<pObj->GetNumVox(); i++){ 
		MaxSE[i] = 0; 
	}
	
	//set up a smaller F = Kx matrix involving just the two blocks involved in each bond (to calculate "F")
	double* TmpK = new double[4*DOFperBlock*DOFperBlock]; //technically only need the upper diagonal
	double* TmpX = new double[2*DOFperBlock]; 
	double* TmpF = new double[2*DOFperBlock];

	float* FBig = new float [DOF*3]; //one for each dimension, so we can keep track of multiple bonds getting added up & average
	for (int i=0; i<3*DOF; i++){FBig[i] = 0;} //initialize to zeros

	for(int bond=0; bond<NumBonds; bond++){ //for each bond!
		int BondDirec = BondDir[bond]; //which direction is this?
		int El1 = IndextoDOF[Indi[bond]];
		int El2 = IndextoDOF[Indj[bond]];

		for (int i=0; i<4*DOFperBlock*DOFperBlock; i++) //zero out them all
			TmpK[i] = 0; 
		for (int i=0; i<2*DOFperBlock; i++){
			TmpX[i] = 0; 
			TmpF[i] = 0; 
		}

		MakeBond(TmpK, bond);

		for (int i=0; i<DOFperBlock; i++){ //set up our little displacement vector
			TmpX[i] = x[El1*DOFperBlock+i];
			TmpX[DOFperBlock + i] = x[El2*DOFperBlock+i];
		}

		//multiply out!
		for (int i=0; i<2*DOFperBlock; i++){ //cycle through each row
			for (int j=i; j<2*DOFperBlock; j++){ //cycle through each column (only for upper diag)
				TmpF[i] += (TmpK[i*2*DOFperBlock+j]*TmpX[j]);
				if (i != j)
					TmpF[j] += (TmpK[i*2*DOFperBlock+j]*TmpX[i]);
			}
		}

		float StrainEnergy = 0;
		for (int i=0; i<2*DOFperBlock; i++){ //cycle through each row
			StrainEnergy += (float)(TmpX[i]*TmpF[i]); //abs value already
		}

		//StrainEnergy = abs(StrainEnergy); //only care about magnitude!
		//check against both bonds!
		if (StrainEnergy > MaxSE[El1])
			MaxSE[El1] = StrainEnergy;
		if (StrainEnergy > MaxSE[El2])
			MaxSE[El2] = StrainEnergy;

		for (int i=0; i<DOFperBlock; i++) { //local forces to universal coordinates
			int CurIndex = DOF*BondDirec + El1*DOFperBlock+i; //first element
			if (FBig[CurIndex] == 0)
				FBig[CurIndex] = (float)abs(TmpF[i]);
			else
				FBig[CurIndex] = (float)(FBig[CurIndex] + abs(TmpF[i]))/2;

			CurIndex = DOF*BondDirec + El2*DOFperBlock+i;

			if (FBig[CurIndex] == 0)
				FBig[CurIndex] = (float)abs(TmpF[DOFperBlock + i]);
			else
				FBig[CurIndex] = (float)(FBig[CurIndex] + abs(TmpF[DOFperBlock + i]))/2;


			b[El1*DOFperBlock+i] += TmpF[i];
			b[El2*DOFperBlock+i] += TmpF[DOFperBlock + i];
		}

		double LinearStrain = abs(x[El1*DOFperBlock + BondDirec] - x[El2*DOFperBlock + BondDirec])/pObj->GetLatticeDim(); //simple volumetric strain (no shear...)
		if (LinearStrain > e[El1*DOFperBlock + BondDirec]) e[El1*DOFperBlock + BondDirec] = LinearStrain;
		if (LinearStrain > e[El2*DOFperBlock + BondDirec]) e[El2*DOFperBlock + BondDirec] = LinearStrain;

	}

	//render FBig to F!
	for (int i=0; i<DOF; i++){ //each element
		for (int j=0; j<3; j++){ //each direction of possible bond
			F[i] += FBig[DOF*j + i];
		}
	}

	delete[]TmpK;
	TmpK = NULL;
	delete[]TmpX;
	TmpX = NULL;
	delete[]TmpF;
	TmpF = NULL;
	delete[]FBig;
	FBig = NULL;

	FindMaxOverall(&Reaction, b, MaxReactions);
	FindMaxOverall(&Force, F, MaxForces);
	FindMaxOverall(&Strain, e, MaxStrains);


}
Esempio n. 3
0
Residue::Residue(StructureBase *parent,
        const CResidue& residue, int moleculeID,
        const ResidueGraphList& standardDictionary,
        const ResidueGraphList& localDictionary,
        int nResidues, int moleculeType) :
    StructureBase(parent), code(NO_CODE), alphaID(NO_ALPHA_ID), type(eOther)
{
    // get ID
    id = residue.GetId().Get();

    // get Residue name
    if (residue.IsSetName()) namePDB = residue.GetName();

    // get CResidue_graph*
    // standard (of correct type) or local dictionary?
    const ResidueGraphList *dictionary = NULL;
    int graphID = 0;
    if (residue.GetResidue_graph().IsStandard() &&
        residue.GetResidue_graph().GetStandard().GetBiostruc_residue_graph_set_id().IsOther_database() &&
        residue.GetResidue_graph().GetStandard().GetBiostruc_residue_graph_set_id().GetOther_database().GetDb() == "Standard residue dictionary" &&
        residue.GetResidue_graph().GetStandard().GetBiostruc_residue_graph_set_id().GetOther_database().GetTag().IsId() &&
        residue.GetResidue_graph().GetStandard().GetBiostruc_residue_graph_set_id().GetOther_database().GetTag().GetId() == 1) {
        dictionary = &standardDictionary;
        graphID = residue.GetResidue_graph().GetStandard().GetResidue_graph_id().Get();
    } else if (residue.GetResidue_graph().IsLocal()) {
        dictionary = &localDictionary;
        graphID = residue.GetResidue_graph().GetLocal().Get();
    } else
        ERRORMSG("confused by Molecule #?, Residue #" << id << "; can't find appropriate dictionary");

    // look up appropriate Residue_graph
    const CResidue_graph *residueGraph = NULL;
    ResidueGraphList::const_iterator i, ie=dictionary->end();
    for (i=dictionary->begin(); i!=ie; ++i) {
        if (i->GetObject().GetId().Get() == graphID) {
            residueGraph = i->GetPointer();
            break;
        }
    }
    if (!residueGraph)
        ERRORMSG("confused by Molecule #?, Residue #" << id << "; can't find Residue-graph ID #" << graphID);

    // get iupac-code if present - assume it's the first character of the first VisibleString
    if (residueGraph->IsSetIupac_code())
        code = residueGraph->GetIupac_code().front()[0];

    // get residue-graph name if present
    if (residueGraph->IsSetDescr()) {
        CResidue_graph::TDescr::const_iterator j, je = residueGraph->GetDescr().end();
        for (j=residueGraph->GetDescr().begin(); j!=je; ++j) {
            if (j->GetObject().IsName()) {
                nameGraph = j->GetObject().GetName();
                break;
            }
        }
    }

    // get type
    if (residueGraph->IsSetResidue_type() &&
            // handle special case of single-residue "heterogens" composed of a natural residue - leave as 'other'
            !(nResidues == 1 &&
                (moleculeType == Molecule::eSolvent || moleculeType == Molecule::eNonpolymer || moleculeType == Molecule::eOther)))
        type = static_cast<eType>(residueGraph->GetResidue_type());

    // get StructureObject* parent
    const StructureObject *object;
    if (!GetParentOfType(&object) || object->coordSets.size() == 0) {
        ERRORMSG("Residue()::Residue() : parent doesn't have any CoordSets");
        return;
    }

    // get atom info
    nAtomsWithAnyCoords = 0;
    CResidue_graph::TAtoms::const_iterator a, ae = residueGraph->GetAtoms().end();
    for (a=residueGraph->GetAtoms().begin(); a!=ae; ++a) {

        const CAtom& atom = a->GetObject();
        int atomID = atom.GetId().Get();
        AtomInfo *info = new AtomInfo;
        AtomPntr ap(moleculeID, id, atomID);

        // see if this atom is present in any CoordSet
        StructureObject::CoordSetList::const_iterator c, ce=object->coordSets.end();
        for (c=object->coordSets.begin(); c!=ce; ++c) {
            if (((*c)->atomSet->GetAtom(ap, true, true))) {
                ++nAtomsWithAnyCoords;
                break;
            }
        }

        info->residue = this;
        // get name if present
        if (atom.IsSetName()) info->name = atom.GetName();
        // get code if present - just use first one of the SEQUENCE
        if (atom.IsSetIupac_code())
            info->code = atom.GetIupac_code().front();
        // get atomic number, assuming it's the integer value of the enumerated type
        CAtom_Base::EElement atomicNumber = atom.GetElement();
        info->atomicNumber = static_cast<int>(atomicNumber);
        // get ionizable status
        if (atom.IsSetIonizable_proton() &&
            atom.GetIonizable_proton() == CAtom::eIonizable_proton_true)
            info->isIonizableProton = true;
        else
            info->isIonizableProton = false;
        // assign (unique) name
        info->glName = parentSet->CreateName(this, atomID);

        // classify atom
        info->classification = ClassifyAtom(this, atom);
        // store alphaID in residue
        if (info->classification == eAlphaBackboneAtom) alphaID = atomID;

        // add info to map
        if (atomInfos.find(atom.GetId().Get()) != atomInfos.end())
            ERRORMSG("Residue #" << id << ": confused by multiple atom IDs " << atom.GetId().Get());
        atomInfos[atomID] = info;
    }

    // get bonds
    CResidue_graph::TBonds::const_iterator b, be = residueGraph->GetBonds().end();
    for (b=residueGraph->GetBonds().begin(); b!=be; ++b) {
        int order = b->GetObject().IsSetBond_order() ?
                b->GetObject().GetBond_order() : Bond::eUnknown;
        const Bond *bond = MakeBond(this,
            moleculeID, id, b->GetObject().GetAtom_id_1().Get(),
            moleculeID, id, b->GetObject().GetAtom_id_2().Get(),
            order);
        if (bond) bonds.push_back(bond);
    }
}