Exemplo n.º 1
0
void traceJigHeader(struct part *part) {
    struct jig *j;
    int i;
    int ncol;

    __p = __line;
    __p += sprintf(__p, "#     Time       ");
    for (i=0; i<part->num_jigs; i++) {
        j = part->jigs[i];
        
	j->data=0.0;
	j->data2=0.0;
	vsetc(j->xdata,0.0);

        switch (j->type) {
        case Ground:        __p += sprintf(__p, "Anchor          "); break;
        case Thermometer:   __p += sprintf(__p, "T.meter         "); break;
        case DihedralMeter: __p += sprintf(__p, "Dihedral        "); break;
        case AngleMeter:    __p += sprintf(__p, "Angle           "); break;
        case RadiusMeter:   __p += sprintf(__p, "Distance        "); break;
        case Thermostat:    __p += sprintf(__p, "T.stat          "); break;
        case LinearMotor:   __p += sprintf(__p, "Lmotor          "); break;
        case RotaryMotor:   __p += sprintf(__p, "speed           torque          ");
	}
    }
    sprintf(__p, "\n");
    write_traceline(__line);
    __p = __line;
    __p += sprintf(__p, "#  picosec      ");

    for (i=0; i<part->num_jigs; i++) {
        j = part->jigs[i];
        ncol = countOutputColumns(j);
        if (ncol > 0) {
            __p += sprintf(__p, " %-15.15s", j->name);
            while (ncol-- > 1)
		// 16 spaces
		__p += sprintf(__p, " %-15.15s", " ");
        }
    }
    if (PrintPotentialEnergy) {
	__p += sprintf(__p, " %-15.15s", "P.Energy");
	__p += sprintf(__p, " %-15.15s", "K.Energy");
	__p += sprintf(__p, " %-15.15s", "T.Energy");
    }
    sprintf(__p, "\n");
    write_traceline(__line);
    __p = __line;
    sprintf(__p, "#\n");
    write_traceline(__line);
}
Exemplo n.º 2
0
void traceJigData(struct part *part, struct xyz *positions) {
    double x;
    int i;
    struct jig *j;

    __p = __line;
    __p += sprintf(__p, "%10.4f ", Iteration * Dt / PICOSEC);
    
    for (i=0; i<part->num_jigs; i++) {
        j = part->jigs[i];
        switch (j->type) {
        case DihedralMeter:
        case AngleMeter:
	    __p += sprintf(__p, " %15.5f", j->data);
	    break;
        case Ground:
	    x=vlen(j->xdata)/1e4;
	    __p += sprintf(__p, " %15.2f", x / j->data);
	    j->data=0.0;
	    vsetc(j->xdata, 0.0);
	    break;
        case RadiusMeter:
        case LinearMotor:
	    // convert from picometers to angstroms
	    __p += sprintf(__p, " %15.4f", 0.01 * j->data);
	    j->data = 0.0;
	    break;
        case Thermometer:
        case Thermostat:
	    __p += sprintf(__p, " %15.2f", j->data);
	    j->data = 0.0;
	    break;
        case RotaryMotor:
	    __p += sprintf(__p, " %15.3f %15.3f", j->data, j->data2);
	    j->data = 0.0;
	    j->data2 = 0.0;
	    break;
	}
    }
    if (PrintPotentialEnergy) {
        double potential_energy = calculatePotential(part, positions);
        double kinetic_energy = calculateKinetic(part);
        
	__p += sprintf(__p, " %15.6f", potential_energy);
	__p += sprintf(__p, " %15.6f", kinetic_energy);
	__p += sprintf(__p, " %15.6f", potential_energy + kinetic_energy);
    }
    sprintf(__p, "\n"); // each snapshot is one line
    write_traceline(__line);
}
Exemplo n.º 3
0
void
oneDynamicsFrame(struct part *part,
                 int iters,
                 struct xyz *averagePositions,
                 struct xyz **pOldPositions,
                 struct xyz **pNewPositions,
                 struct xyz **pPositions,
                 struct xyz *force)
{
    int j;
    int loop;
    double deltaTframe;
    struct xyz f;
    struct xyz *tmp;
    struct jig *jig;
    
    struct xyz *oldPositions = *pOldPositions;
    struct xyz *newPositions = *pNewPositions;
    struct xyz *positions = *pPositions;

    // wware 060109  python exception handling
    NULLPTR(part);
    NULLPTR(averagePositions);
    NULLPTR(oldPositions);
    NULLPTR(newPositions);
    NULLPTR(positions);

    iters = max(iters,1);
    
    deltaTframe = 1.0/iters;
    
    for (j=0; j<part->num_atoms; j++) {
	vsetc(averagePositions[j],0.0);
    }
    
    // See http://www.nanoengineer-1.net/mediawiki/index.php?title=Verlet_integration
    // for a discussion of how dynamics is done in the simulator.

    // we want:
    // x(t+dt) = 2x(t) - x(t-dt) + A dt^2
    // or:
    // newPositions = 2 * positions - oldPositions + A dt^2
    
    // wware 060110  don't handle Interrupted with the BAIL mechanism
    for (loop=0; loop < iters && !Interrupted; loop++) {

	_last_iteration = loop == iters - 1;
        
	Iteration++;
	
	// wware 060109  python exception handling
        updateVanDerWaals(part, NULL, positions); BAIL();
	calculateGradient(part, positions, force); BAIL();
	
        /* first, for each atom, find non-accelerated new pos  */
        /* Atom moved from oldPositions to positions last time,
           now we move it the same amount from positions to newPositions */
        for (j=0; j<part->num_atoms; j++) {
            // f = positions - oldPositions
            vsub2(f,positions[j],oldPositions[j]);
            // newPositions = positions + f
            // or:
            // newPositions = 2 * positions - oldPositions
            vadd2(newPositions[j],positions[j],f);
            // after this, we will need to add A dt^2 to newPositions
        }
	
	// pre-force jigs
	for (j=0;j<part->num_jigs;j++) {	/* for each jig */
	    jig = part->jigs[j];
	    // wware 060109  python exception handling
	    NULLPTR(jig);
	    switch (jig->type) {
	    case LinearMotor:
		jigLinearMotor(jig, positions, newPositions, force, deltaTframe);
		break;
	    default:
		break;
	    }
	}
	
	/* convert forces to accelerations, giving new positions */
	//FoundKE = 0.0;		/* and add up total KE */
	for (j=0; j<part->num_atoms; j++) {
            // to complete Verlet integration, this needs to do:
            // newPositions += A dt^2
            //
            // force[] is in pN, mass is in g, Dt in seconds, f in pm
	    vmul2c(f,force[j],part->atoms[j]->inverseMass); // inverseMass = Dt*Dt/mass

            // XXX: 0.15 probably needs a scaling by Dt
            // 0.15 = deltaX
            // keMax = m v^2 / 2
            // v^2 = 2 keMax / m
            // v = deltaX / Dt = sqrt(2 keMax / m)
            // deltaX = Dt sqrt(2 keMax / m)

            // We probably don't want to do this, because a large raw
            // velocity isn't a problem, it's just when that creates a
            // high force between atoms that it becomes a problem.  We
            // check that elsewhere.
            
	    //if (!ExcessiveEnergyWarning && vlen(f)>0.15) { // 0.15 is just below H flyaway
            // WARNING3("Excessive force %.6f in iteration %d on atom %d -- further warnings suppressed", vlen(f), Iteration, j+1);
            // ExcessiveEnergyWarningThisFrame++;
            //}
	    
	    vadd(newPositions[j],f);
	    
	    //vsub2(f, newPositions[j], positions[j]);
	    //ff = vdot(f, f);
	    //FoundKE += atom[j].energ * ff;
	}
	
	// Jigs are executed in the following order: motors,
	// thermostats, grounds, measurements.  Motions from each
	// motor are added together, then thermostats operate on the
	// motor output.  Grounds override anything that moves atoms.
	// Measurements happen after all things that could affect
	// positions, including grounds.

        // motors
	for (j=0;j<part->num_jigs;j++) {	/* for each jig */
	    jig = part->jigs[j];
	    
	    if (jig->type == RotaryMotor) {
		jigMotor(jig, deltaTframe, positions, newPositions, force);
            }
            // LinearMotor handled in preforce above
	}

        // thermostats
	for (j=0;j<part->num_jigs;j++) {	/* for each jig */
	    jig = part->jigs[j];
	    
	    if (jig->type == Thermostat) {
		jigThermostat(jig, deltaTframe, positions, newPositions);
	    }
	}

        // grounds
	for (j=0;j<part->num_jigs;j++) {	/* for each jig */
	    jig = part->jigs[j];
	    
	    if (jig->type == Ground) {
		jigGround(jig, deltaTframe, positions, newPositions, force);
            }
	}

        // measurements
	for (j=0;j<part->num_jigs;j++) {	/* for each jig */
	    jig = part->jigs[j];
	    
	    switch (jig->type) {
	    case Thermometer:
		jigThermometer(jig, deltaTframe, positions, newPositions);
		break;
	    case DihedralMeter:
		jigDihedral(jig, newPositions);
		break;
	    case AngleMeter:
		jigAngle(jig, newPositions);
		break;
	    case RadiusMeter:
		jigRadius(jig, newPositions);
		break;
            default:
		break;
	    }
	}
	for (j=0; j<part->num_atoms; j++) {
	    vadd(averagePositions[j],newPositions[j]);
	}
	
	tmp=oldPositions; oldPositions=positions; positions=newPositions; newPositions=tmp;
        if (ExcessiveEnergyWarningThisFrame > 0) {
            ExcessiveEnergyWarning = 1;
        }
    }
    
    for (j=0; j<part->num_atoms; j++) {
	vmulc(averagePositions[j],deltaTframe);
    }
    *pOldPositions = oldPositions;
    *pNewPositions = newPositions;
    *pPositions = positions;
}