Exemplo n.º 1
0
void SFGCalculator::DipoleDipoleContribution (morita::MoritaH2O& water, std::vector<double>& dipolePotential) {
	/*********************************************************************************************
	 * Calculation of the frequency shift due to dipole-dipole interaction with neighboring waters
	 *********************************************************************************************/

	//int coord = static_cast<int>(graph->WaterCoordination(&water));
	//int N = graph->NumHBonds(&water);
	//if (N > 3) {
	// two OH bonds on the target water, so we will have two sets of shifts from dipole-dipole interactions

	// the dipole moment derivatives for each OH bond are calculated along the O->H vector, and have a magnitude of the same vector as in the MH paper.
	// For the dipole moment derivative, we can just take the one from the molecular frame and rotate it out to the lab frame
	// Originally the dipole moment derivative was assumed to be along the OH bond... as per DSW below:
	VecR oh1_unit (water.OH1()->normalized());
	VecR oh2_unit (water.OH2()->normalized());

	VecR mu1 (oh1_unit * MU_DERIV_LENGTH);	// these are in atomic units
	VecR mu2 (oh2_unit * MU_DERIV_LENGTH);
	// But perhaps another idea, if taking the actual dipole deriv. doesn't work, is to take the dot product of the actual one with the OH bond unit vector. (?)

	// find the center of mass locations for both target OH bonds
	VecR com1 (water.O()->Position() + (oh1_unit * OH_COM_LENGTH/sfg_units::ANG2BOHR));	// this is in Angstroms...
	VecR com2 (water.O()->Position() + (oh2_unit * OH_COM_LENGTH/sfg_units::ANG2BOHR));

	// Now we go through the calculation of each neighboring H-bonded water (the "source" waters, acting as the "source" of the dipole-dipole interactions) and find the contribution from each OH dipole. First we'll start with source OH's that are bound through the target oxygen. (I'll use the nomenclature of sH to mean source-hydrogen, and tO to mean target oxygen, etc.)

	Atom_ptr_vec hbonds = t.Graph().BondedAtoms(water.O(), hbond);	// all the H's H-bonding to the target O
	for (Atom_it sH = hbonds.begin(); sH != hbonds.end(); sH++) {

		// find the source hydrogen, oxygen, center of mass, oh vector, etc.
		morita::MoritaH2O * sH2O = static_cast<morita::MoritaH2O *>((*sH)->ParentMolecule());
		Atom * sO = sH2O->GetAtom("O");

		VecR sOH (MDSystem::Distance (sO, *sH));
		//VecR sOH (sO->Position().MinVector (sH->Position(), MDSystem::Dimensions()));	// source OH vector
		VecR sCOM (sO->Position() + (sOH.normalized() * (OH_COM_LENGTH/sfg_units::ANG2BOHR)));		// source OH center of mass in angstroms

		// now we have to find the center of mass separation vectors, and also the dipole moment derivatives for each of the source OHs
		VecR sMu (sOH.normalized() * MU_DERIV_LENGTH);		// in atomic units
		// The R vectors point from the source to the target
		VecR R1 (MDSystem::Distance(sCOM,com1));
		VecR R2 (MDSystem::Distance(sCOM,com2));

		// but we are dealing with atomic units, so let's rescale the R vectors to reflect this
		R1 *= sfg_units::ANG2BOHR;
		R2 *= sfg_units::ANG2BOHR;

		dipolePotential[0] += this->DipolePotential (mu1, sMu, R1);		// the result is in atomic units
		dipolePotential[1] += this->DipolePotential (mu2, sMu, R2);
	}

	HDipoleDipoleContribution (water.H1(), mu1, com1, 0, dipolePotential);
	HDipoleDipoleContribution (water.H2(), mu2, com2, 1, dipolePotential);
	//}

	return;
}
Exemplo n.º 2
0
void calc_comforce()
{
  IA_parameters *ia_params;
  std::vector<double> com0 (3), com1 (3);
  double  MofImatrix[9], diff[3];
  double vect0[3], vect1[3], eva[3], eve[3], fvect[3];
  Particle *p;
  int np;
  Cell *cell;
  
  for (int t0=0; t0<n_particle_types-1; t0++) {
    for (int t1=t0+1; t1<n_particle_types; t1++) {
      ia_params = get_ia_param(t0,t1);
      if (ia_params->COMFORCE_flag == 1) {
        com0 = centerofmass(t0);
        com1 = centerofmass(t1);
        for (int i = 0; i < 3; i++) {
          diff[i]=com1[i]-com0[i];
        }
        momentofinertiamatrix(t0, MofImatrix);
        calc_eigenvalues_3x3(MofImatrix, eva);
        /* perpendicular force */
        if(ia_params->COMFORCE_dir == 1) {
          calc_eigenvector_3x3(MofImatrix,eva[0],eve);
          /*By doing two vector products find radial axis along the target system */
          vector_product(eve,diff,vect0);
          vector_product(vect0,eve,vect1);
          
          /* normalize vect1, return is fvect */
          unit_vector(vect1,fvect);
        } else {
          /* parallel force */
          calc_eigenvector_3x3(MofImatrix,eva[0],fvect);
        }
        
        /* orient it along the com vector */
        if (scalar(fvect,diff) < 0.) {
          for (int i = 0; i < 3; i++) {
            fvect[i] = -fvect[i];
          }
        }
        
        /* Now apply the force */
        for (int c = 0; c < local_cells.n; c++) {
          cell = local_cells.cell[c];
          p  = cell->part;
          np = cell->n;
          for(int i = 0; i < np; i++) {
            if(p[i].p.type==t0) {
      	      for(int j = 0; j < 3; j++) {
                p[i].f.f[j] -= ia_params->COMFORCE_fratio * ia_params->COMFORCE_force * fvect[j];
              }
            }
            if(p[i].p.type==t1) {
      	      for (int j = 0; j < 3; j++) {
                p[i].f.f[j] +=  ia_params->COMFORCE_force * fvect[j];
              }
            }
          }
        }
        /*end of force application */
      }
    }
  }
  
}
Exemplo n.º 3
0
void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
  double dfunc, dpoly_ass, md, tq6, itq6, real_z, imag_z; 
  Vector dz, myrealvec, myimagvec, real_dz, imag_dz;
  // The square root of -1
  std::complex<double> ii( 0.0, 1.0 ), dp_x, dp_y, dp_z;

  unsigned ncomp=2*tmom+1;
  double sw, poly_ass, d2, dlen, nbond=0.0; std::complex<double> powered;
  for(unsigned i=1;i<myatoms.getNumberOfAtoms();++i){
      Vector& distance=myatoms.getPosition(i);  // getSeparation( myatoms.getPosition(0), myatoms.getPosition(i) );
      if ( (d2=distance[0]*distance[0])<rcut2 &&
           (d2+=distance[1]*distance[1])<rcut2 &&
           (d2+=distance[2]*distance[2])<rcut2) {
         dlen = sqrt(d2);
         sw = switchingFunction.calculate( dlen, dfunc ); 
   
         nbond += sw;  // Accumulate total number of bonds
         double dlen3 = d2*dlen;

         // Store derivatives of weight
         addAtomDerivatives( -1, 0, (-dfunc)*distance, myatoms );
         addAtomDerivatives( -1, i, (+dfunc)*distance, myatoms );
         myatoms.addTemporyBoxDerivatives( (-dfunc)*Tensor( distance,distance ) ); 

         // Do stuff for m=0
         poly_ass=deriv_poly( 0, distance[2]/dlen, dpoly_ass );
         // Derivatives of z/r wrt x, y, z
         dz = -( distance[2] / dlen3 )*distance; dz[2] += (1.0 / dlen);
         // Derivative wrt to the vector connecting the two atoms
         myrealvec = (+sw)*dpoly_ass*dz + poly_ass*(+dfunc)*distance;
         // Accumulate the derivatives
         addAtomDerivatives( 2 + tmom, 0, -myrealvec, myatoms );      
         addAtomDerivatives( 2 + tmom, i, myrealvec, myatoms); 
         myatoms.addBoxDerivatives( 2 + tmom, Tensor( -myrealvec,distance ) );
         // And store the vector function
         myatoms.addValue( 2 + tmom, sw*poly_ass );

         // The complex number of which we have to take powers
         std::complex<double> com1( distance[0]/dlen ,distance[1]/dlen );

         // Do stuff for all other m values
         for(unsigned m=1;m<=tmom;++m){
             // Calculate Legendre Polynomial
             poly_ass=deriv_poly( m, distance[2]/dlen, dpoly_ass );
             // Calculate powe of complex number
             powered=pow(com1,m-1); md=static_cast<double>(m);
             // Real and imaginary parts of z
             real_z = real(com1*powered); imag_z = imag(com1*powered );
 
             // Calculate steinhardt parameter
             tq6=poly_ass*real_z;   // Real part of steinhardt parameter
             itq6=poly_ass*imag_z;  // Imaginary part of steinhardt parameter

             // Derivatives wrt ( x/r + iy )^m
             dp_x = md*powered*( (1.0/dlen)-(distance[0]*distance[0])/dlen3-ii*(distance[0]*distance[1])/dlen3 );
             dp_y = md*powered*( ii*(1.0/dlen)-(distance[0]*distance[1])/dlen3-ii*(distance[1]*distance[1])/dlen3 );
             dp_z = md*powered*( -(distance[0]*distance[2])/dlen3-ii*(distance[1]*distance[2])/dlen3 );

             // Derivatives of real and imaginary parts of above
             real_dz[0] = real( dp_x ); real_dz[1] = real( dp_y ); real_dz[2] = real( dp_z );
             imag_dz[0] = imag( dp_x ); imag_dz[1] = imag( dp_y ); imag_dz[2] = imag( dp_z );  

             // Complete derivative of steinhardt parameter
             myrealvec = (+sw)*dpoly_ass*real_z*dz + (+dfunc)*distance*tq6 + (+sw)*poly_ass*real_dz; 
             myimagvec = (+sw)*dpoly_ass*imag_z*dz + (+dfunc)*distance*itq6 + (+sw)*poly_ass*imag_dz;

             // Real part
             myatoms.addValue( 2+tmom+m, sw*tq6 );
             addAtomDerivatives( 2+tmom+m, 0, -myrealvec, myatoms );
             addAtomDerivatives( 2+tmom+m, i, myrealvec, myatoms );
             myatoms.addBoxDerivatives( 2+tmom+m, Tensor( -myrealvec,distance ) );
             // Imaginary part 
             myatoms.addValue( 2+ncomp+tmom+m, sw*itq6 );
             addAtomDerivatives( 2+ncomp+tmom+m, 0, -myimagvec, myatoms );
             addAtomDerivatives( 2+ncomp+tmom+m, i, myimagvec, myatoms );
             myatoms.addBoxDerivatives( 2+ncomp+tmom+m, Tensor( -myimagvec,distance ) );
             // Store -m part of vector
             double pref=pow(-1.0,m); 
             // -m part of vector is just +m part multiplied by (-1.0)**m and multiplied by complex
             // conjugate of Legendre polynomial
             // Real part
             myatoms.addValue( 2+tmom-m, pref*sw*tq6 );
             addAtomDerivatives( 2+tmom-m, 0, -pref*myrealvec, myatoms );
             addAtomDerivatives( 2+tmom-m, i, pref*myrealvec, myatoms );
             myatoms.addBoxDerivatives( 2+tmom-m, pref*Tensor( -myrealvec,distance ) );
             // Imaginary part
             myatoms.addValue( 2+ncomp+tmom-m, -pref*sw*itq6 );
             addAtomDerivatives( 2+ncomp+tmom-m, 0, pref*myimagvec, myatoms );
             addAtomDerivatives( 2+ncomp+tmom-m, i, -pref*myimagvec, myatoms );
             myatoms.addBoxDerivatives( 2+ncomp+tmom-m, pref*Tensor( myimagvec,distance ) );
         }
     }
  } 

  // Normalize 
  updateActiveAtoms( myatoms );
  for(unsigned i=0;i<getNumberOfComponentsInVector();++i) myatoms.getUnderlyingMultiValue().quotientRule( 2+i, nbond, 2+i ); 
}
Exemplo n.º 4
0
void Steinhardt::calculateVector(){
  double dfunc, dpoly_ass, md, tq6, itq6, real_z, imag_z; 
  Vector distance, dz, myrealvec, myimagvec, real_dz, imag_dz;
  // The square root of -1
  std::complex<double> ii( 0.0, 1.0 ), dp_x, dp_y, dp_z;

  double sw, poly_ass, dlen, nbond=0.0; std::complex<double> powered;
  for(unsigned i=1;i<getNAtoms();++i){
     distance=getSeparation( getPosition(0), getPosition(i) );
     dlen=distance.modulo(); sw = switchingFunction.calculate( dlen, dfunc );
     if( sw>=getTolerance() ){   
         nbond += sw;  // Accumulate total number of bonds
         double dlen3 = dlen*dlen*dlen;

         // Store derivatives of weight
         MultiColvarBase::addAtomsDerivatives( 0, getAtomIndex(0), (-dfunc)*distance );
         MultiColvarBase::addAtomsDerivatives( 0, getAtomIndex(i), (+dfunc)*distance );
         MultiColvarBase::addBoxDerivatives( 0, (-dfunc)*Tensor( distance,distance ) ); 

         // Do stuff for m=0
         poly_ass=deriv_poly( 0, distance[2]/dlen, dpoly_ass );
         // Derivatives of z/r wrt x, y, z
         dz = -( distance[2] / dlen3 )*distance; dz[2] += (1.0 / dlen);
         // Derivative wrt to the vector connecting the two atoms
         myrealvec = (+sw)*dpoly_ass*dz + poly_ass*(+dfunc)*distance;
         // Accumulate the derivatives
         addAtomsDerivative( tmom, 0, -myrealvec );      
         addAtomsDerivative( tmom, i, myrealvec ); 
         addBoxDerivatives( tmom, Tensor( -myrealvec,distance ) );
         // And store the vector function
         addComponent( tmom, sw*poly_ass );

         // The complex number of which we have to take powers
         std::complex<double> com1( distance[0]/dlen ,distance[1]/dlen );

         // Do stuff for all other m values
         for(unsigned m=1;m<=tmom;++m){
             // Calculate Legendre Polynomial
             poly_ass=deriv_poly( m, distance[2]/dlen, dpoly_ass );
             // Calculate powe of complex number
             powered=pow(com1,m-1); md=static_cast<double>(m);
             // Real and imaginary parts of z
             real_z = real(com1*powered); imag_z = imag(com1*powered );
 
             // Calculate steinhardt parameter
             tq6=poly_ass*real_z;   // Real part of steinhardt parameter
             itq6=poly_ass*imag_z;  // Imaginary part of steinhardt parameter

             // Derivatives wrt ( x/r + iy )^m
             dp_x = md*powered*( (1.0/dlen)-(distance[0]*distance[0])/dlen3-ii*(distance[0]*distance[1])/dlen3 );
             dp_y = md*powered*( ii*(1.0/dlen)-(distance[0]*distance[1])/dlen3-ii*(distance[1]*distance[1])/dlen3 );
             dp_z = md*powered*( -(distance[0]*distance[2])/dlen3-ii*(distance[1]*distance[2])/dlen3 );

             // Derivatives of real and imaginary parts of above
             real_dz[0] = real( dp_x ); real_dz[1] = real( dp_y ); real_dz[2] = real( dp_z );
             imag_dz[0] = imag( dp_x ); imag_dz[1] = imag( dp_y ); imag_dz[2] = imag( dp_z );  

             // Complete derivative of steinhardt parameter
             myrealvec = (+sw)*dpoly_ass*real_z*dz + (+dfunc)*distance*tq6 + (+sw)*poly_ass*real_dz; 
             myimagvec = (+sw)*dpoly_ass*imag_z*dz + (+dfunc)*distance*itq6 + (+sw)*poly_ass*imag_dz;

             // Real part
             addComponent( tmom+m, sw*tq6 );
             addAtomsDerivative( tmom+m, 0, -myrealvec );
             addAtomsDerivative( tmom+m, i, myrealvec );
             addBoxDerivatives( tmom+m, Tensor( -myrealvec,distance ) );
             // Imaginary part 
             addImaginaryComponent( tmom+m, sw*itq6 );
             addImaginaryAtomsDerivative( tmom+m, 0, -myimagvec );
             addImaginaryAtomsDerivative( tmom+m, i, myimagvec );
             addImaginaryBoxDerivatives( tmom+m, Tensor( -myimagvec,distance ) );
             // Store -m part of vector
             double pref=pow(-1.0,m); 
             // -m part of vector is just +m part multiplied by (-1.0)**m and multiplied by complex
             // conjugate of Legendre polynomial
             // Real part
             addComponent( tmom-m, pref*sw*tq6 );
             addAtomsDerivative( tmom-m, 0, -pref*myrealvec );
             addAtomsDerivative( tmom-m, i, pref*myrealvec );
             addBoxDerivatives( tmom-m, pref*Tensor( -myrealvec,distance ) );
             // Imaginary part
             addImaginaryComponent( tmom-m, -pref*sw*itq6 );
             addImaginaryAtomsDerivative( tmom-m, 0, pref*myimagvec );
             addImaginaryAtomsDerivative( tmom-m, i, -pref*myimagvec );
             addImaginaryBoxDerivatives( tmom-m, pref*Tensor( myimagvec,distance ) );
         }
     } else {
         removeAtomRequest( i, sw );
     }
  } 

  // Normalize 
  setElementValue(0, nbond ); updateActiveAtoms();
  for(unsigned i=0;i<2*getNumberOfComponentsInVector();++i) quotientRule( 5+i, 0, 5+i ); 
  // Clear tempory stuff
  clearDerivativesAfterTask(0);
}
Exemplo n.º 5
0
void comk(int k)
{
    struct item* p;
    data d;
    int i, dk, ndk;

    p = sp[-1];
    bidx(sp[-2]);

    /* "getdat" returns the value of the data item which
    * it is called to fetch.  If this is non-zero, just
    * use the existing data on the stack (an example in
    * APL would be "x/y" where x != 0.  If this is zero,
    * the result is the null item, which is created by
    * "newdat" and pushed on the stack.
    */

    if (p->rank == 0 || (p->rank == 1 && p->size == 1)) {
        if (getdat(p)) {
            pop();
            return;
        }
        p = newdat(idx.type, 1, 0);
        pop();
        pop();
        *sp++ = p;
        return;
    }

    if (idx.rank == 0 && p->rank == 1) {
        /* then scalar right arg ok */
        dk = p->dim[0];
        ndk = 0;
        for (i = 0; i < dk; i++) {
            if (getdat(p))
                ndk++;
        }
        p = newdat(idx.type, 1, ndk);
        d = getdat(sp[-2]);
        for (i = 0; i < ndk; i++)
            putdat(p, d);
        pop();
        pop();
        *sp++ = p;
        return;
    }
    if (k < 0 || k >= idx.rank)
        error(ERR_index, "");
    dk = idx.dim[k];
    if (p->rank != 1 || p->size != dk)
        error(ERR_length, "");
    ndk = 0;
    for (i = 0; i < dk; i++) {
        if (getdat(p))
            ndk++;
    }
    p = newdat(idx.type, idx.rank, (idx.size / dk) * ndk);
    copy(IN, (char*)idx.dim, (char*)p->dim, idx.rank);
    p->dim[k] = ndk;
    *sp++ = p;

    indexIterateInit(&idx);
    while (indexIterate(&idx)) {
        com1(k);
    }

    sp--;
    pop();
    pop();
    *sp++ = p;
}
Exemplo n.º 6
0
int main() {
	open_logfile();

	try {

		debug_printf("number of com ports: %d\n", SerialPort::countPorts());
		getchar();

		SerialPort com1(1, 9600, NONE, 8, 1);

		while (1) {
			//com1.printStatus(com1.getStatus());
			debug_printf("-------------\n");
			com1.write(0x42);
			debug_printf(".............\n");
			char d = com1.waitForData();
			if (d != 0)
				debug_printf("read from UART: %X\n", d);
		}

		GuiManager& gui = GuiManager::getInstance();
		gui.init();

		Menu m;
		m.addEntry("hallo");
		m.addEntry("welt");
		m.addEntry("asdfasdfasdf asdfasdf");
		m.addEntry("yet another one");
		m.addEntry("this");
		m.addEntry("or that");
		m.addEntry("or not?");
		m.addEntry("and the last one");

		NumericInput inp(4);
		inp.y = m.y.ref() + m.height.ref();

		gui.getScreen().addWidget(&m);
		gui.getScreen().addWidget(&inp);
		//gui.setFocusTo(m.getEntries().front());
		gui.setFocusTo(&inp);


		Label l("flub");
		l.setInt(inp.value);
		gui.getScreen().addWidget(&l);
		l.x = 200;
		l.y = 20;

		inp.focus_next_up = m.getEntries().back();
		inp.focus_next_down = m.getEntries().front();

		debug_printf("starting gui\n");
		gui.run();

		debug_printf("done, exiting\n");
		close_logfile();
		return EXIT_SUCCESS;
	} catch (Error &e) {
		// non-critical error during init -> quit anyway
		_setvideomode(_DEFAULTMODE);
		debug_printf("ERROR:\n");
		debug_printf(e.what());
		debug_printf("\naborting ...\n");
	}
	catch (CriticalError& e) {
		_setvideomode(_DEFAULTMODE);
		debug_printf("CRITICAL ERROR:\n");
		debug_printf(e.what());
		debug_printf("\naborting ...\n");
	}
	catch (std::runtime_error& e) {
		_setvideomode(_DEFAULTMODE);
		debug_printf("CRITICAL ERROR:\nUnhandled runtime exception:\n");
		debug_printf(e.what());
		debug_printf("\naborting ...\n");
	}
	catch (...) {
		_setvideomode(_DEFAULTMODE);
		debug_printf("CRITICAL ERROR:\nUnknown exception.\naborting ...\n");
	}

	debug_printf("press enter to quit\n");
	getchar();

	close_logfile();
	return EXIT_FAILURE;
}