PolynomialFreeEnergy::PolynomialFreeEnergy(const std::string & name, InputParameters parameters) : DerivativeParsedMaterialHelper(name, parameters), _c("c"), _a_name(getParam<std::string>("c_eq_name")), _W_name(getParam<std::string>("W_name")), _a(_a_name.c_str()), _W(_W_name.c_str()), _order(getParam<MooseEnum>("polynomial_order")) { EBFunction free_energy; // Free energy switch (_order) { case 0: //4th order free_energy(_c, _W, _a) = pow(2.0, 4.0)*_W*pow(_c - _a, 2)*pow(1 - _c - _a, 2); break; case 1: //6th order free_energy(_c, _W, _a) = pow(2.0, 6.0)*_W*( 2.0*pow(_c, 6) - 6.0*pow(_c, 5) + (3.0*_a + 27.0/4.0 - 3.0*_a*_a)*pow(_c, 4) + (-6.0*_a - 7.0/2.0 + 6.0*_a*_a)*pow(_c, 3) + (9.0/2.0*_a - 9.0/2.0*_a*_a + 3.0/4.0)*pow(_c, 2) + (3.0/2.0*_a*_a - 3.0/2.0*_a)*_c); break; case 2: //8th order free_energy(_c, _W, _a) = pow(2.0, 8.0)*_W*(3.0*pow(_c, 8) - 12.0*pow(_c,7) + ( -4.0*_a*_a + 4.0*_a + 20.0 )*pow(_c, 6) + ( 12.0*_a*_a - 12.0*_a - 18.0 )*pow(_c, 5) + ( 15.0*_a + 75.0/8.0 - 15.0*_a*_a )*pow(_c, 4) + ( -10.0*_a - 11.0/4.0 + 10.0*_a*_a )*pow(_c, 3) + ( 15.0/4.0*_a - 15.0/4.0*_a*_a + 3.0/8.0 )*pow(_c, 2) + ( 3.0/4.0*_a*_a - 3.0/4.0*_a )*_c); break; default: mooseError("Error in PolynomialFreeEnergy: incorrect polynomial order"); } std::vector<std::string> nil_str(0); std::vector<Real> nil_real(0); std::vector<std::string> mat_prop_names(2); mat_prop_names[0] = _W_name; mat_prop_names[1] = _a_name; //Parse function functionParse(free_energy, nil_str, nil_str, mat_prop_names, nil_str, nil_real); }
// DEPRECATED CONSTRUCTOR MathEBFreeEnergy::MathEBFreeEnergy(const std::string & deprecated_name, InputParameters parameters) : DerivativeParsedMaterialHelper(deprecated_name, parameters), _c("c") { EBFunction free_energy; //Definition of the free energy for the expression builder free_energy(_c) = 1.0/4.0*( 1.0 + _c )*( 1.0 + _c )*( 1.0 - _c )*( 1.0 - _c ); //Parse function for automatic differentiation functionParse(free_energy); }
PolynomialFreeEnergy::PolynomialFreeEnergy(const InputParameters & parameters) : DerivativeParsedMaterialHelper(parameters), _c("c"), _a("c_eq_name"), _W("W_name"), _order(getParam<MooseEnum>("polynomial_order")) { EBFunction free_energy; // Free energy switch (_order) { case 0: // 4th order free_energy(_c, _W, _a) = pow(2.0, 4.0) * _W * pow(_c - _a, 2) * pow(1 - _c - _a, 2); break; case 1: // 6th order free_energy(_c, _W, _a) = pow(2.0, 6.0) * _W * (2.0 * pow(_c, 6) - 6.0 * pow(_c, 5) + (3.0 * _a + 27.0 / 4.0 - 3.0 * _a * _a) * pow(_c, 4) + (-6.0 * _a - 7.0 / 2.0 + 6.0 * _a * _a) * pow(_c, 3) + (9.0 / 2.0 * _a - 9.0 / 2.0 * _a * _a + 3.0 / 4.0) * pow(_c, 2) + (3.0 / 2.0 * _a * _a - 3.0 / 2.0 * _a) * _c); break; case 2: // 8th order free_energy(_c, _W, _a) = pow(2.0, 8.0) * _W * (3.0 * pow(_c, 8) - 12.0 * pow(_c, 7) + (-4.0 * _a * _a + 4.0 * _a + 20.0) * pow(_c, 6) + (12.0 * _a * _a - 12.0 * _a - 18.0) * pow(_c, 5) + (15.0 * _a + 75.0 / 8.0 - 15.0 * _a * _a) * pow(_c, 4) + (-10.0 * _a - 11.0 / 4.0 + 10.0 * _a * _a) * pow(_c, 3) + (15.0 / 4.0 * _a - 15.0 / 4.0 * _a * _a + 3.0 / 8.0) * pow(_c, 2) + (3.0 / 4.0 * _a * _a - 3.0 / 4.0 * _a) * _c); break; default: mooseError("Error in PolynomialFreeEnergy: incorrect polynomial order"); } // Parse function functionParse(free_energy, {}, {}, {"W_name", "c_eq_name"}, {}, {}); }
VanDerWaalsFreeEnergy::VanDerWaalsFreeEnergy(const InputParameters & parameters) : GasFreeEnergyBase(parameters), _a(getParam<Real>("a")), _b(getParam<Real>("b")), _log_tol(getParam<Real>("log_tol")) { // Definition of the free energy for the expression builder EBFunction free_energy; free_energy(_c, _T) = -_n * _kB * _T * (plog(_nq * (1.0 / _n - _b), _log_tol) + 1.0) - _n * _n * _a; // Parse function for automatic differentiation functionParse(free_energy); }
RegularSolutionFreeEnergy::RegularSolutionFreeEnergy(const InputParameters & parameters) : DerivativeParsedMaterialHelper(parameters), _c("c"), _T("T"), _omega(getParam<Real>("omega")), _kB(getParam<Real>("kB")) { EBFunction free_energy; // Definition of the free energy for the expression builder free_energy(_c) = _omega * _c * (1.0 - _c) + _kB * _T * (_c * log(_c) + (1.0 - _c) * log(1.0 - _c)); // Use Taylor expanded logarithm? if (isParamValid("log_tol")) free_energy.substitute(EBLogPlogSubstitution(getParam<Real>("log_tol"))); // Parse function for automatic differentiation functionParse(free_energy); }
int main(int argc, char *argv[]){ MPI_Init(&argc, &argv); MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &shmcomm); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myid); int i, j, k, n, l, indx, signal; bool flag; double deltat; double time_spend; double begin, end; FILE* energy; FILE* grid; begin = MPI_Wtime(); //read in parameters if(!read_param()){ MPI_Comm_free(&shmcomm); MPI_Finalize(); return 1; } flag = true; dE = 1; el_old = 1; cycle = 0; deltat = (0.1 - dt) / increment; S = 0.25 * (1 + 3 * sqrt(1 - 8 / (3 * U))); // printf("Theoretical value is %lf.\n", third * (1 - third * U) * S * S - 2 * third * third * third * S * S * S * U + U / 9 * S * S * S * S ); if(myid == root){ printf("S is %lf.\n\n", S); //define droplet and boundary, introduce particles, initialize qtensor; if(!initial()){ flag = false; } energy = fopen("energy.out", "w"); fprintf(energy,"cycle\tEnergy_diff\tEnergy_ldg\tEnergy_el\tEnergy_ch\tEnergy_surf\tEnergy_tot\n"); fclose(energy); grid = fopen("grid.bin", "wb"); l = 0; for(l = 0; l < tot; l++){ if(boundary[l] || nboundary[l]) signal = 1; else if(drop[l]) signal = 0; else signal = -1; fwrite(&signal, sizeof(int), 1, grid); } fclose(grid); } //For all infomation initialized in root processor, scatter them to all other processors. if(!scatter()){ flag = false; return 1; } //Evolution while(flag){ //Every 1000 steps calculate energies. if(cycle % 1000 == 0){ free_energy(); if(fabs(dE) < accuracy){ flag = false; } } if(cycle % 10000 == 0){ //Every 10000 steps check the trace of Qtensor if(myid == root){ for(i = 0; i < droplet; i++){ if(!checktr(&q[i * 6])){ flag = false; printf("Error in the trace of q.\n"); } if(flag == false) break; } //print output file output(); } MPI_Bcast(&flag, 1, MPI_BYTE, root, MPI_COMM_WORLD); } //Wait until all the processors are ready and relax the system, first bulk and then boundary. MPI_Barrier(MPI_COMM_WORLD); MPI_Win_fence(0, win); if(flag) relax_bulk(); MPI_Barrier(MPI_COMM_WORLD); MPI_Win_fence(0, win); if(flag) relax_surf(); if(dt < 0.1){ dt += deltat; if(dt >= 0.1) dt = 0.1; } cycle ++; MPI_Barrier(MPI_COMM_WORLD); MPI_Win_fence(0, win); } free_energy(); end = MPI_Wtime(); if(myid == root){ output(); //Calculate time used. time_spend = (double)(end - begin) / 60.0; energy = fopen("energy.out", "a"); if(time_spend < 60){ fprintf(energy, "\nTime used: %lf min.\n", time_spend); printf("\nTime used: %lf min.\n", time_spend); } else{ fprintf(energy, "\nTime used: %lf h.\n", time_spend / 60.0); printf("\nTime used: %lf h.\n", time_spend / 60.0); } fclose(energy); } //deallocate dynamic arrays free_q(); MPI_Win_free(&win); MPI_Comm_free(&shmcomm); MPI_Finalize(); return 0; }
double vbnam1(const unsigned char *x, double *px, int n, int L, int K, const double *lambda0, double *lambda1, const double *alpha0, double *alpha1, double *pz) { FILE *f = fopen("alphavals", "w") ; const unsigned char *x0 = x ; int i, j, a, k, l, iter, x_lj, geno ; double *pz_i, *logpz, *logpz_i, *zeros, *enla, *alpha1_l ; const double *alpha0_l ; double entropy, d_post_prior, E_log_pz, E_log_like, sum_lambda1, tot, tmp, fac ; logpz = pz ; zeros = CALLOC(n * K * NALS, double) ; enla = ALLOC(K, double) ; /* Initialise posteriors equal to priors */ memcpy(alpha1, alpha0, L * K * NALS * sizeof(double)) ; memcpy(lambda1, lambda0, K * sizeof(double)) ; sum_lambda1 = 0 ; for(k = 0 ; k < K ; k++) sum_lambda1 += lambda1[k] ; iter = 0 ; do { memcpy(enla, zeros, K * sizeof(double)) ; memcpy(logpz, zeros, n * K * sizeof(double)) ; d_post_prior = entropy = E_log_pz = E_log_like = 0.0 ; d_post_prior += KL_Dirichlets(lambda1, lambda0, K) ; /* E STEP */ x = x0 ; for(l = 0 ; l < L ; l++) { alpha1_l = alpha1 + l*K*NALS ; alpha0_l = alpha0 + l*K*NALS ; for(k = 0 ; k < K ; k++) // 2008-05-25 *NALS was ommitted d_post_prior += KL_Dirichlets(alpha1_l + k*NALS, alpha0_l + k*NALS, NALS) ; for(j = 0 ; j < 2*n ; j++) { i = j / 2 ; a = j % 2 ; // x_lj = get_allele(&x, a) ; geno = *x - '0' ; x_lj = (geno == 2) || (geno == 1 && a == 1) ; if(a == 1) x++ ; logpz_i = logpz + i*K ; for(k = 0 ; k < K ; k++) { // fprintf(f, "%lf\n", alpha1_l[k*NALS + x_lj]) ; tmp = DIGAMMA(alpha1_l[k*NALS + x_lj]) - DIGAMMA( alpha1_l[k*NALS + 0] + alpha1_l[k*NALS + 1] ) ; // if( isnan(tmp) || tmp > 0 ) ERROR("tmp = %lf: l = %d, i = %d, k = %d\n", tmp, l, i, k) ; logpz_i[k] += tmp ; /* if( isnan(logpz_i[k]) || logpz_i[k] > 0 ) ERROR("logpz[i=%d,k=%d] = %lf, tmp = %lf", i, k, logpz_i[k], tmp) ; */ } } } for(i = 0 ; i < n ; i++) { fac = logpz[i*K + 0] + DIGAMMA(lambda1[0]) - DIGAMMA(sum_lambda1) ; for(k = 0 ; k < K ; k++) { logpz[i*K + k] += DIGAMMA(lambda1[k]) - DIGAMMA(sum_lambda1) ; fac = MAX(fac, logpz[i*K + k]) ; } tot = 0 ; for(k = 0 ; k < K ; k++) { pz[i*K + k] = exp( logpz[i*K + k] - fac ) ; tot += pz[i*K + k] ; } for(k = 0 ; k < K ; k++) { pz[i*K + k] /= tot ; // if(isnan(pz[i*K + k])) ERROR("pz[i=%d,k=%d] = %lf, tot = %lf", i, k, pz[i*K + k], tot) ; enla[k] += pz[i*K + k] ; entropy -= pz[i*K + k] * log( pz[i*K + k] ) ; } } x = x0 ; opt.fit[iter] = free_energy(x, pz, alpha0, alpha1, lambda0, lambda1, n, K, L, iter) ; if(opt.obey_stop_tol && iter >= opt.plateau_size && reached_plateau(iter, opt.fit)) break ; /* M STEP */ x = x0 ; memcpy(alpha1, alpha0, L*K*NALS*sizeof(double)) ; // 2008-05-22 for(l = 0 ; l < L ; l++) { alpha1_l = alpha1 + l*K*NALS ; // memcpy(alpha1_l, alpha0, K*NALS*sizeof(double)) ; 2008-05-22 for(j = 0 ; j < 2*n ; j++) { i = j / 2 ; a = j % 2 ; x_lj = get_allele(&x, a) ; pz_i = pz + i * K ; for(k = 0 ; k < K ; k++) alpha1_l[k*NALS + x_lj] += pz_i[k] ; } } /* insert free energy computation here if you want to do it after M step */ sum_lambda1 = 0 ; memcpy(lambda1, lambda0, K * sizeof(double)) ; for(k = 0 ; k < K ; k++) { // lambda1[k] += enla[k] ; 2008-05-26: not updating lambda, as in Pritchard et al. 2000 sum_lambda1 += lambda1[k] ; } } while(++iter < opt.niters) ; free(zeros) ; free(enla) ; fclose(f) ; return opt.fit[iter - 1] ; }