Esempio n. 1
0
u = TrialFunction(V)
v = TestFunction(V)
a = inner(sigma(u), grad(v)) * dx
L = inner(f, v) * dx

u0 = Function(V)
with u0.vector.localForm() as bc_local:
    bc_local.set(0.0)

# Set up boundary condition on inner surface
bc = DirichletBC(u0, locate_dofs_geometrical(V, boundary))

# Explicitly compile a UFL Form into dolfinx Form
form = Form(a,
            jit_parameters={
                "cffi_extra_compile_args": "-Ofast -march=native",
                "cffi_verbose": True
            })

# Assemble system, applying boundary conditions and preserving symmetry
A = assemble_matrix(form, [bc])
A.assemble()

b = assemble_vector(L)
apply_lifting(b, [a], [[bc]])
b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
set_bc(b, [bc])

# Create solution function
u = Function(V)
Esempio n. 2
0
    values[0] = -args.displ
    return values


displ_top = 0.0

J, F, expr_compiled =\
    fecoda.main.compile_forms(intern_var0, intern_var1, w0, w1, f, g,
                              heat_flux, water_flux, co2_flux, t, dt,
                              [], [dx])

DMG = FunctionSpace(mesh, ("DG", 0))
dmg0 = Function(DMG, name="dmg")

# Define variational problem for projection
proj_rhs = Form(ufl.inner(intern_var0["dmg"], ufl.TestFunction(DMG)) * dx)
mass_DMG = assemble_matrix(
    ufl.inner(ufl.TrialFunction(DMG), ufl.TestFunction(DMG)) * dx, [])
mass_DMG.assemble()

t0 = time()

# Global time loop
for k in range(len(dtimes)):

    t.value = times[k]
    dt.value = dtimes[k]

    if rank == 0:
        logger.info(79 * "#")
        logger.info("Time: {:2.2} days.".format(t.value))
Esempio n. 3
0
def compile_forms(iv0,
                  iv1,
                  w0,
                  w1,
                  f,
                  g,
                  heat_flux,
                  water_flux,
                  co2_flux,
                  t,
                  dt,
                  reb_dx,
                  con_dx,
                  damage_off=False,
                  randomize=0.0):
    """Return Jacobian and residual forms"""

    t0 = time()

    mesh = w0["displ"].function_space.mesh

    # Prepare zero initial guesses, test and trial fctions, global
    w_displ_trial = ufl.TrialFunction(w0["displ"].function_space)
    w_displ_test = ufl.TestFunction(w0["displ"].function_space)

    w_temp_trial = ufl.TrialFunction(w0["temp"].function_space)
    w_temp_test = ufl.TestFunction(w0["temp"].function_space)

    w_phi_trial = ufl.TrialFunction(w0["phi"].function_space)
    w_phi_test = ufl.TestFunction(w0["phi"].function_space)

    w_co2_trial = ufl.TrialFunction(w0["co2"].function_space)
    w_co2_test = ufl.TestFunction(w0["co2"].function_space)

    #
    # Creep, shrinkage strains
    #

    # Autogenous shrinkage increment
    deps_sh_au = (mps.eps_sh_au(t + dt) - mps.eps_sh_au(t))

    # Thermal strain increment
    deps_th = (misc.beta_C * (w1["temp"] - w0["temp"]) * ufl.Identity(3))

    # Drying shrinkage increment
    deps_sh_dr = (mps.k_sh * (w1["phi"] - w0["phi"]) * ufl.Identity(3))

    eta_dash_mid = mps.eta_dash(iv0["eta_dash"], dt / 2.0, w0["temp"],
                                w0["phi"])

    # Prepare creep factors
    beta_cr = mps.beta_cr(dt)
    lambda_cr = mps.lambda_cr(dt, beta_cr)
    creep_v_mid = mps.creep_v(t + dt / 2.0)

    if randomize > 0.0:
        # Randomize Young's modulus
        # This helps convergence at the point where crack initiation begins
        # Randomized E fluctuates uniformly in [E-eps/2, E+eps/2]
        rnd = Function(iv0["eta_dash"].function_space)
        rnd.vector.array[:] = 1.0 - randomize / 2 + np.random.rand(
            *rnd.vector.array.shape) * randomize
    else:
        rnd = 1.0

    E_kelv = rnd * mps.E_kelv(creep_v_mid, lambda_cr, dt, t, eta_dash_mid)

    gamma0 = []
    for i in range(mps.M):
        gamma0.append(iv0[f"gamma_{i}"])

    deps_cr_kel = mps.deps_cr_kel(beta_cr, gamma0, creep_v_mid)
    deps_cr_dash = mps.deps_cr_dash(iv0["sigma"], eta_dash_mid, dt)

    deps_el = mech.eps_el(w1["displ"] - w0["displ"], deps_th, deps_cr_kel,
                          deps_cr_dash, deps_sh_dr, deps_sh_au)

    # Water vapour saturation pressure
    p_sat = water.p_sat(0.5 * (w1["temp"] + w0["temp"]))
    water_cont = water.water_cont(0.5 * (w1["phi"] + w0["phi"]))
    dw_dphi = water.dw_dphi(0.5 * (w1["phi"] + w0["phi"]))

    # Rate of CaCO_3 concentration change
    dot_caco3 = co2.dot_caco3(dt * 24 * 60 * 60, iv0["caco3"], w1["phi"],
                              w1["co2"], w1["temp"])

    #
    # Balances residuals
    #

    sigma_eff = iv0["sigma"] + mech.stress(E_kelv, deps_el)
    eps_eqv = ufl.Max(
        damage_rankine.eps_eqv(sigma_eff, mps.E_static(creep_v_mid)),
        iv0["eps_eqv"])
    f_c = mech.f_c(t)
    f_t = mech.f_t(f_c)
    G_f = mech.G_f(f_c)
    dmg = damage_rankine.damage(eps_eqv, mesh, mps.E_static(creep_v_mid), f_t,
                                G_f)

    # Prepare stress increments
    if damage_off:
        dmg = 0.0 * dmg
        eps_eqv = iv0["eps_eqv"]

    sigma_rebar = mech.stress_rebar(mech.E_rebar, w1["displ"])
    sigma = (1.0 - dmg) * sigma_eff

    _con_dx = []
    for dx in con_dx:
        _con_dx += [dx(metadata={"quadrature_degree": quad_degree_stress})]
    _con_dx = ufl.classes.MeasureSum(*_con_dx)

    _reb_dx = []
    for dx in reb_dx:
        _reb_dx += [dx(metadata={"quadrature_degree": quad_degree_stress})]
    _reb_dx = ufl.classes.MeasureSum(*_reb_dx)

    # Momentum balance for concrete material
    mom_balance = -ufl.inner(sigma, ufl.grad(w_displ_test)) * _con_dx

    # Momentum balance for rebar material
    if len(reb_dx) > 0:
        mom_balance += -ufl.inner(sigma_rebar,
                                  ufl.grad(w_displ_test)) * _reb_dx

    # Add volume body forces
    for measure, force in g.items():
        mom_balance -= ufl.inner(force, w_displ_test) * measure

    # Add surface forces to mom balance
    for measure, force in f.items():
        mom_balance += ufl.inner(force, w_displ_test) * measure

    _thc_dx = []
    for dx in con_dx + reb_dx:
        _thc_dx += [dx(metadata={"quadrature_degree": quad_degree_thc})]
    _thc_dx = ufl.classes.MeasureSum(*_thc_dx)

    # Energy balance = evolution of temperature
    energy_balance = (
        mech.rho_c * misc.C_pc / (dt * 24 * 60 * 60) * ufl.inner(
            (w1["temp"] - w0["temp"]), w_temp_test) * _thc_dx + misc.lambda_c *
        ufl.inner(ufl.grad(w1["temp"]), ufl.grad(w_temp_test)) * _thc_dx +
        water.h_v * water.delta_p * ufl.inner(ufl.grad(
            w1["phi"] * p_sat), ufl.grad(w_temp_test)) * _thc_dx +
        co2.alpha3 * dot_caco3 * w_temp_test * _thc_dx)

    # Water balance = evolution of humidity
    water_balance = (ufl.inner(
        dw_dphi * 1.0 / (dt * 24 * 60 * 60) *
        (w1["phi"] - w0["phi"]), w_phi_test) * _thc_dx + ufl.inner(
            dw_dphi * water.D_ws(water_cont) * ufl.grad(w1["phi"]) +
            water.delta_p * ufl.grad(w1["phi"] * p_sat), ufl.grad(w_phi_test))
                     * _thc_dx + co2.alpha2 * dot_caco3 * w_phi_test * _thc_dx)

    for measure, flux in water_flux.items():
        water_balance -= ufl.inner(flux, w_phi_test) * measure

    co2_balance = (
        ufl.inner(1.0 / (dt * 24 * 60 * 60) *
                  (w1["co2"] - w0["co2"]), w_co2_test) * _thc_dx +
        ufl.inner(co2.D_co2 * ufl.grad(w1["co2"]), ufl.grad(w_co2_test)) *
        _thc_dx + co2.alpha4 * dot_caco3 * w_co2_test * _thc_dx)

    for measure, flux in co2_flux.items():
        co2_balance -= ufl.inner(flux, w_co2_test) * measure

    J_mom = ufl.derivative(mom_balance, w1["displ"], w_displ_trial)

    J_energy_temp = ufl.derivative(energy_balance, w1["temp"], w_temp_trial)
    J_energy_hum = ufl.derivative(energy_balance, w1["phi"], w_phi_trial)
    J_energy_co2 = ufl.derivative(energy_balance, w1["co2"], w_co2_trial)

    J_energy = J_energy_hum + J_energy_temp + J_energy_co2

    J_water_temp = ufl.derivative(water_balance, w1["temp"], w_temp_trial)
    J_water_hum = ufl.derivative(water_balance, w1["phi"], w_phi_trial)
    J_water_co2 = ufl.derivative(water_balance, w1["co2"], w_co2_trial)

    J_water = J_water_temp + J_water_hum + J_water_co2

    J_co2_temp = ufl.derivative(co2_balance, w1["temp"], w_temp_trial)
    J_co2_hum = ufl.derivative(co2_balance, w1["phi"], w_phi_trial)
    J_co2_co2 = ufl.derivative(co2_balance, w1["co2"], w_co2_trial)

    J_co2 = J_co2_temp + J_co2_hum + J_co2_co2

    # Put all Jacobians together
    J_all = J_mom + J_energy + J_water + J_co2

    # Lower algebra symbols and apply derivatives up to terminals
    # This is needed for the Replacer to work properly
    preserve_geometry_types = (ufl.CellVolume, ufl.FacetArea)
    J_all = ufl.algorithms.apply_algebra_lowering.apply_algebra_lowering(J_all)
    J_all = ufl.algorithms.apply_derivatives.apply_derivatives(J_all)
    J_all = ufl.algorithms.apply_geometry_lowering.apply_geometry_lowering(
        J_all, preserve_geometry_types)
    J_all = ufl.algorithms.apply_derivatives.apply_derivatives(J_all)
    J_all = ufl.algorithms.apply_geometry_lowering.apply_geometry_lowering(
        J_all, preserve_geometry_types)
    J_all = ufl.algorithms.apply_derivatives.apply_derivatives(J_all)

    J = extract_blocks(J_all,
                       [w_displ_test, w_temp_test, w_phi_test, w_co2_test],
                       [w_displ_trial, w_temp_trial, w_phi_trial, w_co2_trial])

    J[0][0]._signature = "full" if not damage_off else "dmgoff"

    # Just make sure these are really empty Forms
    assert len(J[1][0].arguments()) == 0
    assert len(J[2][0].arguments()) == 0
    assert len(J[3][0].arguments()) == 0

    F = [-mom_balance, -energy_balance, -water_balance, -co2_balance]

    rank = MPI.COMM_WORLD.rank

    if rank == 0:
        logger.info("Compiling tangents J...")
    J_compiled = [
        Form(J[0][0]),
        [[Form(J[i][j]) for j in range(1, 4)] for i in range(1, 4)]
    ]

    if rank == 0:
        logger.info("Compiling residuals F...")
    F_compiled = [Form(F[0]), [Form(F[i]) for i in range(1, 4)]]

    expr = OrderedDict()

    eta_dash1 = mps.eta_dash(iv0["eta_dash"], dt, w1["temp"], w1["phi"])
    expr["eta_dash"] = (eta_dash1,
                        iv0["eta_dash"].function_space.ufl_element())
    expr["caco3"] = (iv0["caco3"] + dt * 24 * 60 * 60 * dot_caco3,
                     iv0["caco3"].function_space.ufl_element())

    expr["eps_cr_kel"] = (iv0["eps_cr_kel"] + deps_cr_kel,
                          iv0["eps_cr_kel"].function_space.ufl_element())
    expr["eps_cr_dash"] = (iv0["eps_cr_dash"] + deps_cr_dash,
                           iv0["eps_cr_dash"].function_space.ufl_element())

    expr["eps_sh_dr"] = (iv0["eps_sh_dr"] + deps_sh_dr,
                         iv0["eps_sh_dr"].function_space.ufl_element())
    expr["eps_th"] = (iv0["eps_th"] + deps_th,
                      iv0["eps_th"].function_space.ufl_element())

    expr["sigma"] = (iv0["sigma"] + mech.stress(E_kelv, deps_el),
                     iv0["sigma"].function_space.ufl_element())
    expr["eps_eqv"] = (eps_eqv, iv0["eps_eqv"].function_space.ufl_element())
    expr["dmg"] = (dmg, iv0["dmg"].function_space.ufl_element())

    for i in range(mps.M):
        expr[f"gamma_{i}"] = (lambda_cr[i] * (iv1["sigma"] - iv0["sigma"]) +
                              (beta_cr[i]) * gamma0[i],
                              gamma0[i].function_space.ufl_element())

    expr_compiled = OrderedDict()
    for name, item in expr.items():
        if rank == 0:
            logger.info(f"Compiling expressions for {name}...")
        expr_compiled[name] = CompiledExpression(item[0], item[1])

    if rank == 0:
        logger.info(f"[Timer] UFL forms setup and compilation: {time() - t0}")

    return J_compiled, F_compiled, expr_compiled
Esempio n. 4
0
# Controlling compilation parameters
# ----------------------------------
#
# Parameters which control FFCX and JIT compilation could be set
# directly with the interface of :py:class:`Form <dolfinx.fem.Form>` or
# via environmental variables.
#
# This demo shows a mixed approach, where C compilation
# flags are set with environmental variables.
# Some parameters which control FFCX compilation are passed directly to the ``Form``.
# ::

os.environ["DOLFINX_JIT_CFLAGS"] = "-Ofast -march=native"
os.environ["FFCX_VERBOSITY"] = "20"

form = Form(a, form_compiler_parameters={"quadrature_degree": 1})

# The use of such aggresive compiler flags (e.g. ``-Ofast`` violates IEEE floating point standard)
# often results in a faster assembly code, but slower JIT compilation.
# FFCX verbosity levels follow Python std logging library levels, https://docs.python.org/3/library/logging.html.
# To see all available form compiler parameters run ``ffcx --help`` in the commandline.
#
# .. warning::
#    Environmental variables override any other parameters passed to the ``Form``, or directly stated
#    in the metadata of an integral. Please make sure there are no environmental variables set
#    with side-effects.
#
# Assembly and solve
# ------------------
# ::