Changeset f915e1
- Timestamp:
- Apr 18, 2008, 1:30:19 PM (17 years ago)
- Children:
- 995ff3
- Parents:
- 719746
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified pcp/src/run.c ¶
r719746 rf915e1 33 33 #include <gsl/gsl_math.h> 34 34 #include <gsl/gsl_min.h> 35 #include <gsl/gsl_randist.h> 35 36 #include "mpi.h" 36 37 #include "data.h" … … 1198 1199 * \param *params additional arguments, here Problem at hand 1199 1200 */ 1200 double my_f(const gsl_vector *v, void *params)1201 double StructOpt_f(const gsl_vector *v, void *params) 1201 1202 { 1202 1203 struct Problem *P = (struct Problem *)params; … … 1258 1259 } 1259 1260 1260 void my_df(const gsl_vector *v, void *params, gsl_vector *df)1261 void StructOpt_df(const gsl_vector *v, void *params, gsl_vector *df) 1261 1262 { 1262 1263 struct Problem *P = (struct Problem *)params; … … 1273 1274 } 1274 1275 1275 void my_fdf (const gsl_vector *x, void *params, double *f, gsl_vector *df)1276 void StructOpt_fdf (const gsl_vector *x, void *params, double *f, gsl_vector *df) 1276 1277 { 1277 *f = my_f(x, params);1278 my_df(x, params, df);1278 *f = StructOpt_f(x, params); 1279 StructOpt_df(x, params, df); 1279 1280 } 1280 1281 … … 1312 1313 1313 1314 /* Initialize method and iterate */ 1314 minex_func.f = & my_f;1315 minex_func.df = & my_df;1316 minex_func.fdf = & my_fdf;1315 minex_func.f = &StructOpt_f; 1316 minex_func.df = &StructOpt_df; 1317 minex_func.fdf = &StructOpt_fdf; 1317 1318 minex_func.n = np; 1318 1319 minex_func.params = (void *)P; … … 1341 1342 gsl_vector_free(x); 1342 1343 gsl_multimin_fdfminimizer_free (s); 1344 } 1345 1346 /** Implementation of various thermostats. 1347 * All these thermostats apply an additional force which has the following forms: 1348 * -# Woodcock 1349 * \f$p_i \rightarrow \sqrt{\frac{T_0}{T}} \cdot p_i\f$ 1350 * -# Gaussian 1351 * \f$ \frac{ \sum_i \frac{p_i}{m_i} \frac{\partial V}{\partial q_i}} {\sum_i \frac{p^2_i}{m_i}} \cdot p_i\f$ 1352 * -# Langevin 1353 * \f$p_{i,n} \rightarrow \sqrt{1-\alpha^2} p_{i,0} + \alpha p_r\f$ 1354 * -# Berendsen 1355 * \f$p_i \rightarrow \left [ 1+ \frac{\delta t}{\tau_T} \left ( \frac{T_0}{T} \right ) \right ]^{\frac{1}{2}} \cdot p_i\f$ 1356 * -# Nose-Hoover 1357 * \f$\zeta p_i \f$ with \f$\frac{\partial \zeta}{\partial t} = \frac{1}{M_s} \left ( \sum^N_{i=1} \frac{p_i^2}{m_i} - g k_B T \right )\f$ 1358 * These Thermostats either simply rescale the velocities, thus Thermostats() should be called after UpdateIonsU(), and/or 1359 * have a constraint force acting additionally on the ions. In the latter case, the ion speeds have to be modified 1360 * belatedly and the constraint force set. 1361 * \param *P Problem at hand 1362 * \param i which of the thermostats to take: 0 - none, 1 - Woodcock, 2 - Gaussian, 3 - Langevin, 4 - Berendsen, 5 - Nose-Hoover 1363 * \sa InitThermostat() 1364 */ 1365 void Thermostats(struct Problem *P, enum thermostats i) 1366 { 1367 struct FileData *Files = &P->Files; 1368 struct Ions *I = &P->Ion; 1369 int is, ia, d; 1370 double *U; 1371 double a, ekin = 0.; 1372 double E = 0., F = 0.; 1373 double delta_alpha = 0.; 1374 const int delta_t = P->R.delta_t; 1375 double ScaleTempFactor; 1376 double sigma; 1377 gsl_rng * r; 1378 const gsl_rng_type * T; 1379 1380 // calculate current temperature 1381 CalculateEnergyIonsU(P); // Temperature now in I->ActualTemp 1382 ScaleTempFactor = P->R.TargetTemp/I->ActualTemp; 1383 //if ((P->Par.me == 0) && (I->ActualTemp < MYEPSILON)) fprintf(stderr,"Thermostat: (1) I->ActualTemp = %lg",I->ActualTemp); 1384 if (Files->MeOutMes) fprintf(Files->TemperatureFile, "%d\t%lg",P->R.OuterStep, I->ActualTemp); 1385 1386 // differentating between the various thermostats 1387 switch(i) { 1388 case None: 1389 debug(P, "Applying no thermostat..."); 1390 break; 1391 case Woodcock: 1392 if ((P->R.ScaleTempStep > 0) && ((P->R.OuterStep-1) % P->R.ScaleTempStep == 0)) { 1393 debug(P, "Applying Woodcock thermostat..."); 1394 for (is=0; is < I->Max_Types; is++) { 1395 a = 0.5*I->I[is].IonMass; 1396 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1397 U = &I->I[is].U[NDIM*ia]; 1398 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces 1399 for (d=0; d<NDIM; d++) { 1400 U[d] *= sqrt(ScaleTempFactor); 1401 ekin += 0.5*I->I[is].IonMass * U[d]*U[d]; 1402 } 1403 } 1404 } 1405 } 1406 break; 1407 case Gaussian: 1408 debug(P, "Applying Gaussian thermostat..."); 1409 for (is=0; is < I->Max_Types; is++) { // sum up constraint constant 1410 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1411 U = &I->I[is].U[NDIM*ia]; 1412 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces 1413 for (d=0; d<NDIM; d++) { 1414 F += U[d] * I->I[is].FIon[d+NDIM*ia]; 1415 E += U[d]*U[d]*I->I[is].IonMass; 1416 } 1417 } 1418 } 1419 if (P->Call.out[ValueOut]) fprintf(stderr, "(%i) Gaussian Least Constraint constant is %lg\n", P->Par.me, F/E); 1420 for (is=0; is < I->Max_Types; is++) { // apply constraint constant on constraint force and on velocities 1421 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1422 U = &I->I[is].U[NDIM*ia]; 1423 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces 1424 for (d=0; d<NDIM; d++) { 1425 I->I[is].FConstraint[d+NDIM*ia] = (F/E) * (U[d]*I->I[is].IonMass); 1426 U[d] += delta_t/I->I[is].IonMass * (I->I[is].FConstraint[d+NDIM*ia]); 1427 ekin += 0.5*I->I[is].IonMass * U[d]*U[d]; 1428 } 1429 } 1430 } 1431 break; 1432 case Langevin: 1433 debug(P, "Applying Langevin thermostat..."); 1434 // init random number generator 1435 gsl_rng_env_setup(); 1436 T = gsl_rng_default; 1437 r = gsl_rng_alloc (T); 1438 // Go through each ion 1439 for (is=0; is < I->Max_Types; is++) { 1440 sigma = sqrt(P->R.TargetTemp/I->I[is].IonMass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime) 1441 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1442 U = &I->I[is].U[NDIM*ia]; 1443 // throw a dice to determine whether it gets hit by a heat bath particle 1444 if (((((rand()/(double)RAND_MAX))*P->R.TempFrequency) < 1.)) { // (I->I[is].IMT[ia] == MoveIon) && even FixedIon moves, only not by other's forces 1445 if (P->Par.me == 0) fprintf(stderr,"(%i) Particle %i,%i was hit (sigma %lg): %lg -> ", P->Par.me, is, ia, sigma, sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2])); 1446 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis 1447 for (d=0; d<NDIM; d++) { 1448 U[d] = gsl_ran_gaussian (r, sigma); 1449 } 1450 if (P->Par.me == 0) fprintf(stderr,"%lg\n", sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2])); 1451 } 1452 for (d=0; d<NDIM; d++) 1453 ekin += 0.5*I->I[is].IonMass * U[d]*U[d]; 1454 } 1455 } 1456 break; 1457 case Berendsen: 1458 debug(P, "Applying Berendsen-VanGunsteren thermostat..."); 1459 for (is=0; is < I->Max_Types; is++) { 1460 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1461 U = &I->I[is].U[NDIM*ia]; 1462 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces 1463 for (d=0; d<NDIM; d++) { 1464 U[d] *= sqrt(1+(P->R.delta_t/P->R.TempFrequency)*(ScaleTempFactor-1)); 1465 ekin += 0.5*I->I[is].IonMass * U[d]*U[d]; 1466 } 1467 } 1468 } 1469 break; 1470 case NoseHoover: 1471 debug(P, "Applying Nose-Hoover thermostat..."); 1472 // dynamically evolve alpha (the additional degree of freedom) 1473 delta_alpha = 0.; 1474 for (is=0; is < I->Max_Types; is++) { // sum up constraint constant 1475 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1476 U = &I->I[is].U[NDIM*ia]; 1477 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces 1478 for (d=0; d<NDIM; d++) { 1479 delta_alpha += U[d]*U[d]*I->I[is].IonMass; 1480 } 1481 } 1482 } 1483 delta_alpha = (delta_alpha - (3.*I->Max_TotalIons+1.) * P->R.TargetTemp)/(P->R.HooverMass*Units2Electronmass); 1484 P->R.alpha += delta_alpha*delta_t; 1485 if (P->Par.me == 0) fprintf(stderr,"(%i) alpha = %lg * %i = %lg\n", P->Par.me, delta_alpha, delta_t, P->R.alpha); 1486 // apply updated alpha as additional force 1487 for (is=0; is < I->Max_Types; is++) { // apply constraint constant on constraint force and on velocities 1488 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { 1489 U = &I->I[is].U[NDIM*ia]; 1490 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces 1491 for (d=0; d<NDIM; d++) { 1492 I->I[is].FConstraint[d+NDIM*ia] = - P->R.alpha * (U[d] * I->I[is].IonMass); 1493 U[d] += delta_t/I->I[is].IonMass * (I->I[is].FConstraint[d+NDIM*ia]); 1494 ekin += (0.5*I->I[is].IonMass) * U[d]*U[d]; 1495 } 1496 } 1497 } 1498 break; 1499 } 1500 I->EKin = ekin; 1501 I->ActualTemp = (2./(3.*I->Max_TotalIons)*I->EKin); 1502 //if ((P->Par.me == 0) && (I->ActualTemp < MYEPSILON)) fprintf(stderr,"Thermostat: (2) I->ActualTemp = %lg",I->ActualTemp); 1503 if (Files->MeOutMes) { fprintf(Files->TemperatureFile, "\t%lg\n", I->ActualTemp); fflush(Files->TemperatureFile); } 1343 1504 } 1344 1505
Note:
See TracChangeset
for help on using the changeset viewer.