Ejemplo n.º 1
0
def transient_pipe_flow_1D(
    npipes, nx, dof, nphases,
    pipe_length,
    initial_time,
    final_time,
    initial_time_step,
    dt_min,
    dt_max,
    initial_solution,    
    impl_python=False
    ):
    
    # Time Stepper (TS) for ODE and DAE
    # DAE - https://en.wikipedia.org/wiki/Differential_algebraic_equation
    # https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/
    ts = PETSc.TS().create()
    #ts.createPython(MyTS(), comm=PETSc.COMM_SELF)
    
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/DM/index.html
    pipes = []
    for i in range(npipes):
        boundary_type = PETSc.DMDA.BoundaryType.GHOSTED
        da = PETSc.DMDA().create([nx], dof=dof, stencil_width=1, stencil_type='star', boundary_type=boundary_type)
        da.setFromOptions()
        pipes.append(da)
    
    # Create a redundant DM, there is no petsc4py interface (yet)
    # so we created our own wrapper
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/DM/DMREDUNDANT.html
#     dmredundant = PETSc.DM().create()
#     dmredundant.setType(dmredundant.Type.REDUNDANT)
#     CompositeSimple1D.redundantSetSize(dmredundant, 0, dof)
#     dmredundant.setDimension(1)
#     dmredundant.setUp()

    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/DM/DMCOMPOSITE.html
    dm = PETSc.DMComposite().create()
    
    for pipe in pipes:        
        dm.addDM(pipe)

#     dm.addDM(dmredundant)
#     CompositeSimple1D.compositeSetCoupling(dm)
    CompositeSimple1D.registerNewSNES()
    
    ts.setDM(dm)
        
    F = dm.createGlobalVec()

    if impl_python:     
        α0 = initial_solution.reshape((nx,dof))[:, nphases:-1]
        pde = Flow(dm, nx, dof, pipe_length, nphases, α0)
        ts.setIFunction(pde.evalFunction, F)
    else:
        # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetIFunction.html
        assert False, 'C function not implemented yet!'
#         ts.setIFunction(CompositeSimple1D.formFunction, F,
#                          args=(conductivity, source_term, wall_length, temperature_presc))    
    
    snes = ts.getSNES()
    
    snes.setUpdate(pde.updateFunction)
    
    x = dm.createGlobalVec()    

    x[...] = initial_solution

    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetDuration.html
    ts.setDuration(max_time=final_time, max_steps=None)
    
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetInitialTimeStep.html
    ts.setInitialTimeStep(initial_time=initial_time, initial_time_step=initial_time_step)
    
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetProblemType.html
    ts.setProblemType(ts.ProblemType.NONLINEAR)
    ts.setEquationType(ts.EquationType.IMPLICIT)
    
    prev_sol = initial_solution.copy()
    
#     restart = PreStep(prev_sol)
#     ts.setPreStep(restart.prestep)
#     ts.setPostStep(restart.poststep)
    
    options = PETSc.Options()
    options.setValue('-ts_adapt_dt_min', dt_min)
    options.setValue('-ts_adapt_dt_max', dt_max)
    
    ts.setFromOptions()

    snes = ts.getSNES()
    if options.getString('snes_type') in [snes.Type.VINEWTONRSLS, snes.Type.VINEWTONSSLS]:
#     if True:
#         snesvi = snes.getCompositeSNES(1)
        snesvi = snes
        
        xl = np.zeros((nx, dof))
        xl[:,:nphases] = -100
        xl[:,-1] = 0
        xl[:, nphases:-1] = 0

        
        xu = np.zeros((nx, dof))    
        xu[:,:nphases] =  100
        xu[:,-1] = 1000
        xu[:, nphases:-1] = 1
             
        xlVec = dm.createGlobalVec()
        xuVec = dm.createGlobalVec()   
        xlVec.setArray(xl.flatten())
        xuVec.setArray(xu.flatten())    

        snesvi.setVariableBounds(xlVec, xuVec)
    
    ts.solve(x)
    
#     while ts.diverged:
#         x[...] = prev_sol.copy()
#         ts.setInitialTimeStep(initial_time=initial_time, initial_time_step=0.5*initial_time_step)
#         ts.solve(x)
    
    final_dt = ts.getTimeStep()
    
    return x, final_dt
Ejemplo n.º 2
0
def transient_heat_transfer_1D(
    npipes, nx, 
    initial_temperature,
    temperature_presc, 
    conductivity,
    source_term,
    wall_length,
    final_time,
    initial_time_step,
    impl_python=False
    ):
    
    # Time Stepper (TS) for ODE and DAE
    # DAE - https://en.wikipedia.org/wiki/Differential_algebraic_equation
    # https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/
    ts = PETSc.TS().create()

    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/DM/index.html
    #
    pipes = []
    for i in range(npipes):
        pipes.append(PETSc.DMDA().create([nx],dof=1, stencil_width=1, stencil_type='star'))
    
    # Create a redundant DM, there is no petsc4py interface (yet)
    # so we created our own wrapper
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/DM/DMREDUNDANT.html
    dmredundant = PETSc.DM().create()
    dmredundant.setType(dmredundant.Type.REDUNDANT)
    HeatTransfer1D.redundantSetSize(dmredundant, 0, 1)
    dmredundant.setDimension(1)
    dmredundant.setUp()

    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/DM/DMCOMPOSITE.html
    dm = PETSc.DMComposite().create()
    
    for pipe in pipes:        
        dm.addDM(pipe)

    dm.addDM(dmredundant)
    HeatTransfer1D.compositeSetCoupling(dm)
    
    ts.setDM(dm)

    F = dm.createGlobalVec()

    if impl_python:        
        ode = Heat(dm, temperature_presc, conductivity, source_term, wall_length)
        ts.setIFunction(ode.evalFunction, F)
    else:
        # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetIFunction.html
        ts.setIFunction(HeatTransfer1D.formFunction, F,
                         args=(conductivity, source_term, wall_length, temperature_presc))    
    
    x = dm.createGlobalVec()
    
    x[...] = initial_temperature
    
    #HeatTransfer1D.formInitGuess(x, dm, initial_temperature)

    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetDuration.html
    ts.setDuration(max_time=final_time, max_steps=None)
    
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetExactFinalTime.html
    ts.setExactFinalTime(ts.ExactFinalTimeOption.STEPOVER)
    
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetInitialTimeStep.html
    ts.setInitialTimeStep(initial_time=0.0, initial_time_step=initial_time_step)
    
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSSetProblemType.html
    ts.setProblemType(ts.ProblemType.NONLINEAR)
    
    # Another way to set the solve type is through PETSc.Options()
    #ts.setType(ts.Type.CRANK_NICOLSON)
    #ts.setType(ts.Type.THETA)
    #ts.setTheta(theta=0.9999)
    #ts.setType(ts.Type.EIMEX) # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/TS/TSEIMEX.html
    #ts.setType(ts.Type.BDF      )

    ts.setFromOptions()

    ts.solve(x)

    return x