// This file is part of the brownmove simulation package // // (C) 2003 - 2009 Tihamer Geyer // tihamer.geyer@bioinformatik.uni-saarland.de // // Check for Updates at the Project Homepage // http://service.bioinformatik.uni-saarland.de/brownmove #include "interactingBody.h" #include "molecule.h" #include "hishape.h" namespace brown{ void (*HiShape::tensor) (diffusionMatrix& D, const doublevec &myPos, const double myR, const doublevec &otherPos, const double otherR, bool doesRotate) = NULL; HiShape::HiShape(const HiShape &other){ doublevec_set(myPosition, other.myPosition); radius = other.radius; HICutOff = other.HICutOff; } HiShape::~HiShape(){ } std::string HiShape::describe(){ ostringstream ausgabe("", ios::out); int i=0; ausgabe << "radius = " << radius; return(ausgabe.str()); } void HiShape::recalculate(const fullPosition &p) { doublevec_set(myPosition, p.pos); } void HiShape::initForces(const fullForce &rF, const fullForce &eF) { // std::cerr << "HiShape::initForces" << std::endl; doublevec_set(rawRandomForce.f, rF.f); doublevec_set(rawRandomForce.t, rF.t); doublevec_set(rawExternalForce.f, eF.f); doublevec_set(rawExternalForce.t, eF.t); // reset effective forces doublevec_set(effRandomForce.f, 0.0); doublevec_set(effRandomForce.t, 0.0); doublevec_set(effExternalForce.f, 0.0); doublevec_set(effExternalForce.t, 0.0); // also reset HI corrections factors for(int i = 0; i<6; i++) { Ci_sum[i] = 0.0; } } double HiShape::getHiCorrections(HiShape *otherHiS, bool includeRotation) { diffusionMatrix coupling; int i, k; fullForce otherForce; fullForce myContrib, otherContrib; // if(includeRotation) { // std::cerr << "HiShape::getHiCorrections with Rotation" << std::endl; // } else { // std::cerr << "HiShape::getHiCorrections - no Rotation" << std::endl; // } // determine distance and compare to cut-off doublevec abstand; doublevec_set(abstand, myPosition); doublevec_sub(abstand, otherHiS->getPosition()); double wieWeit = doublevec_length(abstand); // std::cerr << "HiShape::getHiCorrections: distance = " << wieWeit << std::endl; if(wieWeit <= HICutOff) { // std::cerr << "HiShape::getHiCorrections:inside cutoff radius "<< HICutOff << " - determining HI" << std::endl; // set up 6x6 HI-Tensor with includeRotation double otherRadius = otherHiS->getRadius(); tensor(coupling, myPosition, radius, otherHiS->getPosition(), otherRadius, includeRotation); // calculate HI corrections for external forces doublevec_set(otherForce.f, otherHiS->getRawExternalForce().f); doublevec_set(otherForce.t, otherHiS->getRawExternalForce().t); transform(myContrib.f, myContrib.t, coupling, otherForce.f, otherForce.t); // other acting on me transform_T(otherContrib.f, otherContrib.t, coupling, rawExternalForce.f, rawExternalForce.t); // me onto other // std::cerr << "HiShape::getHiCorrections: otherForce.f = " <addEffExternal(otherContrib); // std::cerr << "HiShape::getHiCorrections: effExternalForce.f = " <getRawRandomForce().f); doublevec_set(otherForce.t, otherHiS->getRawRandomForce().t); transform(myContrib.f, myContrib.t, coupling, otherForce.f, otherForce.t); // other acting on me transform_T(otherContrib.f, otherContrib.t, coupling, rawRandomForce.f, rawRandomForce.t); // me onto other doublevec_mult(myContrib.f, radius); doublevec_mult(myContrib.t, radius); doublevec_mult(otherContrib.f, otherRadius); doublevec_mult(otherContrib.t, otherRadius); addEffRandom(myContrib); otherHiS->addEffRandom(otherContrib); // correction factors: epsilon double eps_sum = 0.0; double myCi[6], otherCi[6]; double Dik, Dii; for(i=0; i<6; i++) { myCi[i] = 0.0; otherCi[i] = 0.0; } #ifdef HI_WITH_ROTATION for(i=0; i<6; i++) { for(k=i+1; k<6; k++) #else for(i=0; i<3; i++) { // ### Hi-Change ### for(k=0; k<3; k++) // ### Hi-Change ### #endif { Dik = coupling[i][k]; eps_sum += Dik; myCi[i] += Dik*Dik; otherCi[k] += Dik*Dik; // std::cerr << "HiShape::getHiCorrections: myCi = " << myCi[0]<<", "< 2 radii // if(distance >= (radius + otherRadius)) // { // Trans-Trans-Part: 3/4rij (1 + rij*rij) + 1/4 (ai^2+aj^2)/rij^3 ( 1 - 3rij*rij) // tmp1 tmp2 // trMat_set(tmp1,1.0); // set identity trMat_add(tmp1,dyadmat); // add dyadic product trMat_mult(tmp1,0.75/distance); // prefactor trMat_set(tmp2, 1.0); // set identity trMat_set(tmp3, dyadmat); // tmp3 = 3 (r_ij * r_ij) trMat_mult(tmp3, 3.0); trMat_sub(tmp2, tmp3); // (1 - 3 rij*rij) trMat_mult(tmp2, 0.25*ai2aj2*o_rij3); // tmp2 = 1/4 (ai^2+aj^2)/rij^3 (I - 3 (r_ij*r_ij)) trMat_add(tmp1,tmp2); // tmp1 = 3/4r_ij * ( I + r_ij*r_ij ) + 1/4 (ai^2+aj^2)/rij^3 (I - 3 (r_ij*r_ij)) // } //done, set the translation part of the diffusion Matrix mat.set(tmp1,0); if(doesRotate) { // Rotation-Rotation: 3/8rij^3 (3 rij*rij - 1) trMat_set(tmp1,1.0); // set identity trMat_set(tmp2, dyadmat); // 3 rij*rij trMat_mult(tmp2, 3.0); trMat_sub(tmp2, tmp1); // 3 rij*rij - 1 trMat_mult(tmp2, 0.375*o_rij3); // prefactor 3/8rij^3 mat.set(tmp2, 3); // Trans-Rot = Rot-Trans^T: -3/4r^2 eijk rij // tmp1 = epsilon r_ij (don't forget the minus signs!!!) tmp1[0][0] = 0.0 ; tmp1[0][1] = -distvec[2]; tmp1[0][2] = distvec[1] ; tmp1[1][0] = distvec[2] ; tmp1[1][1] = 0.0 ; tmp1[1][2] = -distvec[0]; tmp1[2][0] = -distvec[1]; tmp1[2][1] = distvec[0] ; tmp1[2][2] = 0.0 ; // trMat_mult(tmp1, (-0.75 * a_rij2)); // -0.75 * a/rij^2 * epsilon r_ij trMat_mult(tmp1, (0.75 * o_rij2)); // -0.75 * o/rij^2 * epsilon r_ij // set the Trans-Rot part of the diffusionMatrix mat.set(tmp1,1); // RT = TR^T -> multiply by (-1) and set the Rot-Trans part of the diffusionMatrix // trMat_mult(tmp1, -1.0); mat.set(tmp1,2); } else { trMat_set(tmp1, 0.0); // set 3x3 Null-matrix mat.set(tmp1, 1); // and zero the rest of the diffusion matrix mat.set(tmp1, 2); mat.set(tmp1, 3); } // debug output // std::cerr << "RotnePrager: "< 2 radii // if(distance >= (radius + otherRadius)) // { // // Trans-Trans-Part: 3a/4rij (1 + rij*rij) + 1/2 (a/rij)^3 ( 1 - 3rij*rij) // // tmp1 tmp2 // // // trMat_set(tmp1,1.0); // set identity // trMat_add(tmp1,dyadmat); // add dyadic product // trMat_mult(tmp1,0.75*a_rij); // prefactor // // trMat_set(tmp2, 1.0); // set identity // trMat_set(tmp3, dyadmat); // tmp3 = 3 (r_ij * r_ij) // trMat_mult(tmp3, 3.0); // trMat_sub(tmp2, tmp3); // (1 - 3 rij*rij) // trMat_mult(tmp2, 0.5*a3_rij3); // tmp2 = 1/2 (a/r_ij)^3 (I - 3 (r_ij*r_ij)) // // trMat_add(tmp1,tmp2); // tmp1 = 3a/4r_ij * ( I + r_ij*r_ij ) + 1/2 (a/r_ij)^3 (I - 3 (r_ij*r_ij)) // } // else // { // // Trans-Trans: (1 - 9rij/32a) * 1 + 3rij/32a * (rij*rij) // // tmp1 tmp2 // // // trMat_set(tmp1, 1.0); // set identity // trMat_mult(tmp1, 1.0 - 9/(32*a_rij)); // prefactor // // trMat_set(tmp2, dyadmat); // dyadic product for second term // trMat_mult(tmp2, 3.0/(32*a_rij)); // prefactor // // trMat_add(tmp1, tmp2); // sum up // } // //done, set the translation part of the diffusion Matrix // mat.set(tmp1,0); // // if(doesRotate) // { // // Rotation-Rotation: 3a/8rij^3 (3 rij*rij - 1) // trMat_set(tmp1,1.0); // set identity // trMat_set(tmp2, dyadmat); // 3 rij*rij // trMat_mult(tmp2, 3.0); // trMat_sub(tmp2, tmp1); // 3 rij*rij - 1 // trMat_mult(tmp2, 0.375*a_rij3); // prefactor 3a/8rij^3 // // mat.set(tmp2, 3); // // // Trans-Rot = Rot-Trans^T: -3a/4r^2 eijk rij // // tmp1 = epsilon r_ij (don't forget the minus signs!!!) // tmp1[0][0] = 0.0 ; tmp1[0][1] = -distvec[2]; tmp1[0][2] = distvec[1] ; // tmp1[1][0] = distvec[2] ; tmp1[1][1] = 0.0 ; tmp1[1][2] = -distvec[0]; // tmp1[2][0] = -distvec[1]; tmp1[2][1] = distvec[0] ; tmp1[2][2] = 0.0 ; // // // trMat_mult(tmp1, (-0.75 * a_rij2)); // -0.75 * a/rij^2 * epsilon r_ij // trMat_mult(tmp1, (0.75 * a_rij2)); // -0.75 * a/rij^2 * epsilon r_ij // // // set the Trans-Rot part of the diffusionMatrix // mat.set(tmp1,1); // // // RT = TR^T -> multiply by (-1) and set the Rot-Trans part of the diffusionMatrix // // trMat_mult(tmp1, -1.0); // mat.set(tmp1,2); // } // else // { // trMat_set(tmp1, 0.0); // set 3x3 Null-matrix // mat.set(tmp1, 1); // and zero the rest of the diffusion matrix // mat.set(tmp1, 2); // mat.set(tmp1, 3); // } // // // // debug output // std::cerr << "RotnePrager: "<