Ejemplo n.º 1
0
  SolutionInstance TubeMCM::Integrate(d dt){ // Integrate using
					     // MacCormack method
    d t=sol.getTime();
    d newt=t+dt;

    d lambda=dt/dx;

    SolutionInstance predictor(gp);
    {				// Predictor step
      const vd& oldrho=sol.rho();
      const vd& oldm=sol.m();
      const vd& oldrhoE=sol.rhoE();
    
      vd& prho=predictor.rho_ref();
      vd& pm=predictor.m_ref();
      vd& prhoE=predictor.rhoE_ref();
      // Fluxes from previous solution
      vd Cflux=sol.Cflux();
      vd Mflux=sol.Mflux();
      vd Eflux=sol.Eflux();

      // Density
      prho.tail(gp-1)=oldrho.tail(gp-1)
	-lambda*(Cflux.tail(gp-1)-Cflux.head(gp-1));
      // The first element
      prho(0)=oldrho(0)-lambda*(Cflux(1)-Cflux(0));

      // Momentum
      d oldu0=oldm(0)/oldrho(0);
      d momfluxl = pow(oldm(0), 2)/oldrho(0) + pleft(t);

      pm.tail(gp-1)=oldm.tail(gp-1)
	-lambda*(Mflux.tail(gp-1)-Mflux.head(gp-1));
      // The first element
      pm(0)=oldm(0)-lambda*(Mflux(1)-momfluxl);
      pm(gp-1)=0;

      // Energy
      prhoE.tail(gp-1)=oldrhoE.tail(gp-1)
	-lambda*(Eflux.tail(gp-1)-Eflux.head(gp-1));
      // The first element
      prhoE(0)=oldrhoE(0)-lambda*(Eflux(1)-Eflux(0));

    }
    SolutionInstance corrector(gp);
    // Temp test hack:
    corrector=predictor;
    corrector.setTime(newt);

    return corrector;
  }					     // Integrate(dt)
Ejemplo n.º 2
0
void Cconfig::iterate(double time_step)
{ 	
	dt=time_step;
	dt_on_2 = dt/2.;
	dt2_on_2=dt*dt/2.;
	
	predictor();			//motion integration
	
	update_contact();		//find contact and get the force and torque
	sum_force(); 			//sum the force moment of each contact on particle   
	if(simule_thermal_conduction) sum_heat(); 					//Heat transfer 
	
	//AK addition
	if(MELT_SURFTEN){melt_dist();}
	
	cell.rigid_velocity *= 0.0;
	corrector();			//acceleration of particles according to the sum of force/moment they experience
	cell.rigid_velocity /= parameter.total_mass;

// Velocity offset by rigid motion
#pragma omp parallel for num_threads(NTHREADS)	// YG, MPI
	for(int ip=0; ip< P.size(); ip++) 
		P[ip].V -= cell.rigid_velocity;
}
Ejemplo n.º 3
0
void Cconfig::iterate(double time_step)
{ 	
	dt=time_step;
	dt_on_2 = dt/2.;
	dt2_on_2=dt*dt/2.;
	
	predictor();			//motion integration
	
	update_contact();		//find contact and get the force and torque
	sum_force(); 			//sum the force moment of each contact on particle   
	if(simule_thermal_conduction) sum_heat(); 					//Heat transfer 
	
	if(LIQUID_TRANSFER) liquid_transfer();
	
	// water input, controlling water volume
	if(LIQUID_TRANSFER){
	for(int ip=0; ip< P.size(); ip++) 
	{
		// initial
		if(dt==0) P[ip].water_volume = parameter.INITIAL_SATURATION * P[ip].void_volume;
		if(P[ip].X.x[0]>=-0.5 && P[ip].X.x[0]<=0.5)
			P[ip].water_volume = parameter.FIXED_SATURATION * P[ip].void_volume; //exp
		P[ip].saturation = P[ip].water_volume/P[ip].void_volume; // update the saturation of each cell
		if(P[ip].saturation > MAX_SATURATION) P[ip].saturation = MAX_SATURATION; //exp
	}}

	cell.rigid_velocity *= 0.0;
	corrector();			//acceleration of particles according to the sum of force/moment they experience
	cell.rigid_velocity /= parameter.total_mass;
	// Velocity offset by rigid motion
//#pragma omp parallel for num_threads(NTHREADS)	// YG, MPI
//	for(int ip=0; ip< P.size(); ip++) 
//		P[ip].V -= cell.rigid_velocity;

	if(dt==0) {
		for(int ip=0; ip< P.size(); ip++) P[ip].V *= 0.0;}
			
	for(int ip=0; ip< P.size(); ip++) {
		P[ip].V *= (1.0 - 1.0*dt); // Global damping
		P[ip].Ome *= (1.0 - 1.0*dt);
		}
		
	// calculation of global and local water pressure.
	cap_pressure=0;
	for(int ip=0; ip< P.size(); ip++) {
		P[ip].water_pressure = 0.0;}
		
	for(int ic=0;ic<C.size();ic++) if(C[ic].fcap >0) {
//		cap_pressure -= C[ic].fcap * C[ic].dx;
		P[C[ic].A].water_pressure -= C[ic].fcap * C[ic].dx * P[C[ic].A].R /(P[C[ic].A].R+P[C[ic].B].R);
		P[C[ic].B].water_pressure -= C[ic].fcap * C[ic].dx * P[C[ic].B].R /(P[C[ic].A].R+P[C[ic].B].R);
	}
	for(int ip=0; ip< P.size(); ip++) {
// Modified effective stress term with the degree of saturation (micro-scale).
		if(P[ip].voronoi_volume>1.0e-10) P[ip].water_pressure /= (3.0 *P[ip].voronoi_volume);
		P[ip].positive_pressure = 0.0;
		if(P[ip].saturation > 1.0) {
			P[ip].positive_pressure = WATER_K*parameter.SURFACE_TENSION *(P[ip].saturation - 1.0); // positive pressure
			P[ip].water_pressure += P[ip].positive_pressure;
			}
		if(P[ip].saturation>=1.0e-10) P[ip].water_pressure /= P[ip].saturation;
		}
		
	//Overall saturation and pressure
	saturation = 0.0;
//	cap_pressure = 0.0;
	double void_volume=0.0;
	double water_volume=0.0;
	
	for(int ip=0; ip< P.size(); ip++){
		void_volume += P[ip].void_volume;
		water_volume += P[ip].water_volume;
// Modified effective stress term with the degree of saturation (macro-scale).
//		if(P[ip].saturation <= 1.0) cap_pressure -= P[ip].water_pressure * P[ip].water_volume; // modified cap pressure
//			else cap_pressure -= P[ip].water_pressure * P[ip].void_volume;
		cap_pressure -= P[ip].water_pressure * P[ip].saturation *P[ip].voronoi_volume;
	}
	saturation = water_volume / void_volume;
	if(saturation<1.0e-10) saturation = 1.e-10;
	double total_volume = cell.L.x[0]* cell.L.x[1]* cell.L.x[2];
	cap_pressure /= saturation * total_volume;
	water_content = water_volume /total_volume;
}
Ejemplo n.º 4
0
void Cconfig::iterate(double time_step)
{ 	
	dt=time_step;
	dt_on_2 = dt/2.;
	dt2_on_2=dt*dt/2.;
	
	predictor();			//motion integration
	
	update_contact();		//find contact and get the force and torque
	sum_force(); 			//sum the force moment of each contact on particle   
	if(simule_thermal_conduction) sum_heat(); 					//Heat transfer 
	
	if(LIQUID_TRANSFER) liquid_transfer();
	
	// water input, controlling water volume
	if(LIQUID_TRANSFER){

	if(dt==0) flag_wetting = true;

	for(int ip=0; ip< P.size(); ip++) 
	{
		// initial
		if(dt==0) {P[ip].water_volume = parameter.INITIAL_SATURATION * P[ip].void_volume;
			P[ip].water_volume_old = P[ip].water_volume; }

		
		if(P[ip].void_volume <= 1e-3 * P[ip].grain_volume) 
			P[ip].void_volume = 1e-3 * P[ip].grain_volume; // avoid negative Void volume
			
		P[ip].saturation = P[ip].water_volume/P[ip].void_volume; // update the saturation of each cell
		if(P[ip].saturation > MAX_SATURATION) P[ip].saturation = MAX_SATURATION; //exp
	}}
	
	if(!LIQUID_TRANSFER){ // for pre-packing stage
	for(int ip=0; ip< P.size(); ip++) 
	{
		P[ip].saturation = 0.1;
		P[ip].water_volume = 0.1 * P[ip].void_volume; }}

	cell.rigid_velocity *= 0.0;
	corrector();			//acceleration of particles according to the sum of force/moment they experience
	cell.rigid_velocity /= parameter.total_mass;
// Velocity offset by rigid motion
//#pragma omp parallel for num_threads(NTHREADS)	// YG, MPI
	for(int ip=0; ip< P.size(); ip++) 
		P[ip].V -= cell.rigid_velocity;

	if(dt==0) {
		for(int ip=0; ip< P.size(); ip++) P[ip].V *= 0.0;}
			
	for(int ip=0; ip< P.size(); ip++) {
		P[ip].V *= (1.0 - GLOBAL_DAMPING*dt); // Global damping
		P[ip].Ome *= (1.0 - GLOBAL_DAMPING*dt);
		}
		
	// calculation of global and local water pressure.
	for(int ip=0; ip< P.size(); ip++) {
		P[ip].water_pressure = 0.0;}
		
	for(int ic=0;ic<C.size();ic++) if(C[ic].fcap >0) {
		P[C[ic].A].water_pressure -= C[ic].fcap * C[ic].dx * P[C[ic].A].R /(P[C[ic].A].R+P[C[ic].B].R);
		P[C[ic].B].water_pressure -= C[ic].fcap * C[ic].dx * P[C[ic].B].R /(P[C[ic].A].R+P[C[ic].B].R);
	}
	for(int ip=0; ip< P.size(); ip++) {
// Modified effective stress term with the degree of saturation (micro-scale).
		if(P[ip].voronoi_volume>1.0e-10) P[ip].water_pressure /= (3.0 *P[ip].voronoi_volume);
		P[ip].positive_pressure = 0.0;
		if(P[ip].saturation > MAX_SATURATION_AIR && P[ip].saturation < 1.0) {
			P[ip].positive_pressure = 
				AIR_K *(P[ip].saturation - MAX_SATURATION_AIR)/(1.0 - P[ip].saturation); // positive pressure
			P[ip].water_pressure += P[ip].positive_pressure*1.0; // air compression the whole cell experiencing the pressure
			}
		if(P[ip].saturation>=1.0e-10) P[ip].water_pressure /= P[ip].saturation;
	}
		
	//Overall saturation and pressure
	saturation = 0.0;
	cap_pressure = 0.0;
	double void_volume=0.0;
	double water_volume=0.0;
	double total_volume_mid = 0.0;
	
	cap_pressure_mid = 0.0;
	double void_volume_mid=0.0;
	double water_volume_mid=0.0;
	
	for(int ip=0; ip< P.size(); ip++){
		void_volume += P[ip].void_volume;
		water_volume += P[ip].water_volume;
// Modified effective stress term with the degree of saturation (macro-scale).
//		if(P[ip].saturation <= 1.0) cap_pressure -= P[ip].water_pressure * P[ip].water_volume; // modified cap pressure
//			else cap_pressure -= P[ip].water_pressure * P[ip].void_volume;
		cap_pressure -= P[ip].water_pressure * P[ip].saturation *P[ip].voronoi_volume;
		if(P[ip].X.x[1] <= 5.0 && P[ip].X.x[1] >= -5.0){
			void_volume_mid += P[ip].void_volume;
			water_volume_mid += P[ip].water_volume;
			cap_pressure_mid -= P[ip].water_pressure * P[ip].saturation *P[ip].voronoi_volume;
			total_volume_mid += P[ip].voronoi_volume;
		}
	}
	saturation = water_volume / void_volume;
	if(saturation < 1.0e-10) saturation = 1.e-10;
	double total_volume = cell.L.x[0]* cell.L.x[1]* cell.L.x[2];
	cap_pressure /= saturation * total_volume;
	water_content = water_volume /total_volume;
	
	saturation_mid = water_volume_mid / void_volume_mid;
	if(saturation_mid<1.0e-10) saturation_mid = 1.e-10;
	if(total_volume_mid > 0.0){
		cap_pressure_mid /= saturation_mid * total_volume_mid;
		water_content_mid = water_volume_mid /total_volume_mid;
	}
	
	if(saturation >= MAX_SCAN && t>1.0 && flag_wetting)	flag_wetting=false;
	if(saturation <= MIN_SCAN && t>1.0 && !flag_wetting) flag_wetting=true;

}
Ejemplo n.º 5
0
// asynchronous step solver
int e_trsolver::stepsolve_async(nr_double_t steptime)
{
    // Start to sweep through time.
    int error = 0;
    convError = 0;

    time = steptime;
    // update the interpolation time of any externally controlled
    // components which require it.
    updateExternalInterpTime(time);
    // make the stored histories for all ircuits that have
    // requested them at least as long as the next major time
    // step so we can reject the step later if needed and
    // restore all the histories to their previous state
    updateHistoryAges (time - lastasynctime);

    //delta = (steptime - time) / 10;
    //if (progress) logprogressbar (i, swp->getSize (), 40);
#if DEBUG && 0
    messagefcn (LOG_STATUS, "NOTIFY: %s: solving netlist for t = %e\n",
              getName (), (double) time);
#endif

    do
    {
#if STEPDEBUG
        if (delta == deltaMin)
        {
            messagefcn (LOG_ERROR,
                      "WARNING: %s: minimum delta h = %.3e at t = %.3e\n",
                      getName (), (double) delta, (double) current);
        }
#endif
        // update the integration coefficients
        updateCoefficients (delta);

        // Run predictor to get a start value for the solution vector for
        // the successive iterative corrector process
        error += predictor ();

        // restart Newton iteration
        if (rejected)
        {
            restart ();      // restart non-linear devices
            rejected = 0;
        }

        // Run corrector process with appropriate exception handling.
        // The corrector iterates through the solutions of the integration
        // process until a certain error tolerance has been reached.
        try_running () // #defined as:    do {
        {
            error += corrector ();
        }
        catch_exception () // #defined as:   } while (0); if (estack.top ()) switch (estack.top()->getCode ())
        {
        case EXCEPTION_NO_CONVERGENCE:
            pop_exception ();

            // Reduce step-size (by half) if failed to converge.
            if (current > 0) current -= delta;
            delta /= 2;
            if (delta <= deltaMin)
            {
                delta = deltaMin;
                adjustOrder (1);
            }
            if (current > 0) current += delta;

            // Update statistics.
            statRejected++;
            statConvergence++;
            rejected++;
            converged = 0;
            error = 0;

            // Start using damped Newton-Raphson.
            convHelper = CONV_SteepestDescent;
            convError = 2;
#if DEBUG
            messagefcn (LOG_ERROR, "WARNING: delta rejected at t = %.3e, h = %.3e "
                      "(no convergence)\n", (double) saveCurrent, (double) delta);
#endif
            break;
        default:
            // Otherwise return.
            estack.print ();
            error++;
            break;
        }
        if (error) return -1;
        if (rejected) continue;

        // check whether Jacobian matrix is still non-singular
        if (!A->isFinite ())
        {
            messagefcn (LOG_ERROR, "ERROR: %s: Jacobian singular at t = %.3e, "
                      "aborting %s analysis\n", getName (), (double) current,
			getDescription ().c_str());
            return -1;
        }

        // Update statistics and no more damped Newton-Raphson.
        statIterations += iterations;
        if (--convError < 0) convHelper = 0;

        // Now advance in time or not...
        if (running > 1)
        {
            adjustDelta (time);
            adjustOrder ();
        }
        else
        {
            fillStates ();
            nextStates ();
            rejected = 0;
        }

        saveCurrent = current;
        current += delta;
        running++;
        converged++;

        // Tell integrators to be running.
        setMode (MODE_NONE);

        // Initialize or update history.
        if (running > 1)
        {
            updateHistory (saveCurrent);
        }
        else
        {
            initHistory (saveCurrent);
        }
    }
    while (saveCurrent < time); // Hit a requested time point?

    return 0;
}
Ejemplo n.º 6
0
/* synchronous step solver for external ode routine
 *
 * This function solves the circuit for a single time delta provided
 * by an external source. Convergence issues etc. are expected to
 * be handled by the external solver, as it is in full control of the
 * time stepping.
 */
int e_trsolver::stepsolve_sync(nr_double_t synctime)
{

    int error = 0;
    convError = 0;

    time = synctime;
    // update the interpolation time of any externally controlled
    // components which require it.
    updateExternalInterpTime(time);

    // copy the externally chosen time step to delta
    delta = time - lastsynctime;

    // get the current solution time
    //current += delta;

    // updates the integrator coefficients, and updates the array of prev
    // 8 deltas with the new delta for this step
    updateCoefficients (delta);

    // Run predictor to get a start value for the solution vector for
    // the successive iterative corrector process
    error += predictor ();

    // restart Newton iteration
    restart (); // restart non-linear devices

    // Attempt to solve the circuit with the given delta
    try_running () // #defined as:    do {
    {
        //error += solve_nonlinear_step ();
        error += corrector ();
    }
    catch_exception () // #defined as:   } while (0); if (estack.top ()) switch (estack.top()->getCode ())
    {
    case EXCEPTION_NO_CONVERGENCE:
        pop_exception ();

        // Retry using damped Newton-Raphson.
        this->convHelper = CONV_SteepestDescent;
        convError = 2;
#if DEBUG
        messagefcn (LOG_ERROR, "WARNING: delta rejected at t = %.3e, h = %.3e "
                  "(no convergence)\n", (double) saveCurrent, (double) delta);
#endif

        try_running () // #defined as:    do {
        {
//            error += solve_nonlinear_step ();
            error += solve_nonlinear ();
        }
        catch_exception () // #defined as:   } while (0); if (estack.top ()) switch (estack.top()->getCode ())
        {
        case EXCEPTION_NO_CONVERGENCE:
            pop_exception ();

            // Update statistics.
            statRejected++;
            statConvergence++;
            rejected++;
            converged = 0;
            error = 0;

            break;
        default:
            // Otherwise return.
            estack.print ();
            error++;
            break;
        }

        // Update statistics and no more damped Newton-Raphson.
//        statIterations += iterations;
//        if (--convError < 0) this->convHelper = 0;


        break;
    default:
        // Otherwise return.
        estack.print ();
        error++;
        break;
    }
    // if there was an error other than non-convergence, return -1
    if (error) return -1;

    // check whether Jacobian matrix is still non-singular
    if (!A->isFinite ())
    {
//        messagefcn (LOG_ERROR, "ERROR: %s: Jacobian singular at t = %.3e, "
//                  "aborting %s analysis\n", getName (), (double) current,
//                  getDescription ());
        return -1;
    }

    return 0;
}