Пример #1
0
static vumatptr load(const char* n){
  typedef std::vector<VUMATPtrHandler> VUMATPtrContainer;
  static LibrariesHandler libraries;
  static VUMATPtrContainer fcts;
#ifdef HAVE_STD_MUTEX
   static std::mutex m;
   std::lock_guard<std::mutex> lock(m);
#else /* HAVE_STD_MUTEX */
   lock l;
#endif  /* HAVE_STD_MUTEX */
  try{
    VUMATPtrContainer::const_iterator p;
    p = std::find_if(fcts.begin(),fcts.end(),VUMATNameCompare(n));
    if(p==fcts.end()){
      const std::pair<std::string,std::string> lf = decompose(n);
      const std::string& lib = lf.first;
      const std::string& fct = lf.second;
      if(lib.empty()){
	report("","","",n);
	return NULLPTR(vumatptr);
      }
#if (defined _WIN32 || defined _WIN64) && (!defined __CYGWIN__)
      libptr l = ::LoadLibrary(TEXT (lib.c_str()));
#else
      libptr l = ::dlopen(lib.c_str(),RTLD_NOW);
#endif
      if(l==NULLPTR(libptr)){
#if (defined _WIN32 || defined _WIN64) && (!defined __CYGWIN__)
	report(lib,"",getLastWin32Error(),n);
#else
	report(lib,"",::dlerror(),n);
#endif	
	return NULLPTR(vumatptr);
      }
      libraries.insert(std::make_pair(lib,l));
      union {
	void *ptr;
	vumatptr f;
      } r;
#if (defined _WIN32 || defined _WIN64) && (!defined __CYGWIN__)
      r.f = reinterpret_cast<vumatptr>(::GetProcAddress(l,fct.c_str()));
#else
      r.ptr = ::dlsym(l,fct.c_str());
#endif
      if(r.ptr==NULLPTR(void *)){
#if (defined _WIN32 || defined _WIN64) && (!defined __CYGWIN__)
	report(lib,fct,getLastWin32Error(),n);
#else
	report(lib,fct,::dlerror(),n);
#endif	
	return NULLPTR(vumatptr);
      }
      VUMATPtrHandler h;
      h.name = std::string(n,n+80);
      h.ptr  = r.f;
      fcts.push_back(h);
      return r.f;
    }
    return p->ptr;
  }
Пример #2
0
void
evaluateGradient(struct configuration *p)
{
    struct functionDefinition *fd;
    int i;
    double gradientCoordinate;

    NULLPTR(p);
    fd = p->functionDefinition;
    NULLPTR(fd);
    if (p->gradient == NULL) {
	p->gradient = (double *)allocate(sizeof(double) * fd->dimension);
	if (fd->dfunc == NULL) {
	    evaluateGradientFromPotential(p); BAIL();
	} else {
	    (*fd->dfunc)(p); BAIL();
	}
	fd->gradientEvaluationCount++;
	p->parameter = 0.0;
	p->maximumCoordinateInGradient = 0.0;
	for (i=fd->dimension-1; i>=0; i--) {
	    CHECKNAN(p->gradient[i]);
	    gradientCoordinate = fabs(p->gradient[i]);
	    if (p->maximumCoordinateInGradient < gradientCoordinate) {
		p->maximumCoordinateInGradient = gradientCoordinate;
	    }
	}
    }
}
Пример #3
0
void
evaluateGradientFromPotential(struct configuration *p)
{
    struct functionDefinition *fd;
    struct configuration *pPlusDelta = NULL;
    struct configuration *pMinusDelta = NULL;
    int i;
    int j;

    NULLPTR(p);
    fd = p->functionDefinition;
    NULLPTR(fd);
    if (fd->gradient_delta == 0.0) {
	fd->gradient_delta = 1e-8;
    }
    for (i=0; i<fd->dimension; i++) {
	pPlusDelta = makeConfiguration(fd);
	for (j=0; j<fd->dimension; j++) {
	    pPlusDelta->coordinate[j] = p->coordinate[j];
	}
	pPlusDelta->coordinate[i] += fd->gradient_delta / 2.0;

	pMinusDelta = makeConfiguration(fd);
	for (j=0; j<fd->dimension; j++) {
	    pMinusDelta->coordinate[j] = p->coordinate[j];
	}
	pMinusDelta->coordinate[i] -= fd->gradient_delta / 2.0;

	p->gradient[i] = (evaluate(pMinusDelta) - evaluate(pPlusDelta)) / fd->gradient_delta;
	BAIL();
	SetConfiguration(&pPlusDelta, NULL);
	SetConfiguration(&pMinusDelta, NULL);
    }
}
Пример #4
0
void
initializeFunctionDefinition(struct functionDefinition *fd,
                             void (*func)(struct configuration *p),
                             int dimension,
                             int messageBufferLength)
{
    NULLPTR(func);
    fd->func = func;
    fd->dfunc = NULL;
    fd->freeExtra = NULL;
    fd->termination = NULL;
    fd->constraints = NULL;
    fd->tolerance = 1e-8;
    fd->algorithm = PolakRibiereConjugateGradient;
    fd->linear_algorithm = LinearMinimize;
    fd->gradient_delta = 1e-8;
    fd->dimension = dimension;
    fd->initial_parameter_guess = 1.0;
    fd->parameter_limit = MAXDOUBLE;
    fd->functionEvaluationCount = 0;
    fd->gradientEvaluationCount = 0;
    if (messageBufferLength > 0) {
        fd->message = (char *)allocate(messageBufferLength);
        fd->message[0] = '\0';
        fd->messageBufferLength = messageBufferLength;
    } else {
        fd->message = "";
        fd->messageBufferLength = 0;
    }
    fd->allocationCount = 0;
    fd->freeCount = 0;
    fd->maxAllocation = 0;
}
Пример #5
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;
}