예제 #1
0
def fenics(sim_params, file_inputs, output_params, passive_params, hs_params,
           cell_ion_params, monodomain_params, windkessel_params, pso):
    i, j = indices(2)
    #global i
    #global j

    # We don't do pressure control simulations, probably will get rid of this.
    ispressurectrl = False

    #------------------## Load in all information and set up simulation --------

    ## Assign input/output parameters
    output_path = output_params["output_path"][0]
    casename = file_inputs["casename"][0]

    # Assign parameters for Windkessel
    # will be moving circulatory to its own module and pass in dictionary
    # similar to cell_ion module
    Cao = windkessel_params["Cao"][0]
    Cven = windkessel_params["Cven"][0]
    Vart0 = windkessel_params["Vart0"][0]
    Vven0 = windkessel_params["Vven0"][0]
    Rao = windkessel_params["Rao"][0]
    Rven = windkessel_params["Rven"][0]
    Rper = windkessel_params["Rper"][0]
    V_ven = windkessel_params["V_ven"][0]
    V_art = windkessel_params["V_art"][0]

    # --------  Assign parameters for active force calculation  ----------------

    filament_compliance_factor = hs_params["myofilament_parameters"][
        "filament_compliance_factor"][0]
    no_of_states = hs_params["myofilament_parameters"]["num_states"][0]
    no_of_attached_states = hs_params["myofilament_parameters"][
        "num_attached_states"][0]
    no_of_detached_states = no_of_states - no_of_attached_states
    no_of_transitions = hs_params["myofilament_parameters"]["num_transitions"][
        0]
    state_attached = hs_params["myofilament_parameters"]["state_attached"][0]
    cb_extensions = hs_params["myofilament_parameters"]["cb_extensions"][0]
    k_cb_multiplier = hs_params["myofilament_parameters"]["k_cb_multiplier"][0]
    k_cb_pos = hs_params["myofilament_parameters"]["k_cb_pos"][0]
    k_cb_neg = hs_params["myofilament_parameters"]["k_cb_neg"][0]
    cb_number_density = hs_params["cb_number_density"][0]
    alpha_value = hs_params["myofilament_parameters"]["alpha"][0]
    x_bin_min = hs_params["myofilament_parameters"]["bin_min"][0]
    x_bin_max = hs_params["myofilament_parameters"]["bin_max"][0]
    x_bin_increment = hs_params["myofilament_parameters"]["bin_width"][0]
    hsl_min_threshold = hs_params["myofilament_parameters"]["passive_l_slack"][
        0]
    hsl_max_threshold = hs_params["myofilament_parameters"][
        "hsl_max_threshold"][0]
    xfiber_fraction = hs_params["myofilament_parameters"]["xfiber_fraction"][0]

    ## ---------  Set up information for active force calculation --------------

    # Create x interval for cross-bridges
    xx = np.arange(x_bin_min, x_bin_max + x_bin_increment, x_bin_increment)

    # Define number of intervals cross-bridges are defined over
    no_of_x_bins = np.shape(xx)[0]

    # Define the length of the populations vector
    n_array_length = no_of_attached_states * no_of_x_bins + no_of_detached_states + 2  # +2 for binding sites on/off

    # Need to work out a general way to set this based on the scheme
    n_vector_indices = [[0, 0], [1, 1], [2, 2 + no_of_x_bins - 1]]

    #------------  Start setting up simulation ---------------------------------
    sim_duration = sim_params["sim_duration"][0]
    save_output = sim_params["save_output"][0]
    step_size = sim_params["sim_timestep"][0]
    loading_number = sim_params["loading_number"][0]
    if sim_params["sim_geometry"][0] == "ventricle" or sim_params[
            "sim_geometry"][0] == "ventricle_lclee_2" or sim_params[
                "sim_geometry"][0] == "ventricle_physloop":
        # For ventricle for now, specify number of cardiac cycles
        cycles = sim_params["sim_type"][1]
        meshfilename = sim_params["sim_type"][2]
    # Cardiac cycle length and number of cycles will be general
    # For now, just including this info in the input file
    BCL = sim_duration  # ms

    hsl0 = hs_params["initial_hs_length"][
        0]  # this is now set when creating mesh
    no_of_time_steps = int(cycles * BCL / step_size)
    no_of_cell_time_steps = int(BCL / step_size)

    deg = 4
    parameters["form_compiler"]["quadrature_degree"] = deg
    parameters["form_compiler"]["representation"] = "quadrature"

    # Clear out any old results files
    os.system("rm " + output_path + "*.pvd")
    os.system("rm " + output_path + "*.vtu")

    #--------------- Load in mesh, initialize things from it -------------------

    mesh = Mesh()
    f = HDF5File(mpi_comm_world(), meshfilename, 'r')
    f.read(mesh, casename, False)

    if casename == "ellipsoidal":
        #loading_number = 25;
        ugrid = vtk_py.convertXMLMeshToUGrid(mesh)
        ugrid = vtk_py.rotateUGrid(ugrid, sx=0.11, sy=0.11, sz=0.11)
        mesh = vtk_py.convertUGridToXMLMesh(ugrid)

        #don't need to do the vtk_py mesh stuff
    else:  #assuming we are using a patient specific mesh
        ugrid = vtk_py.convertXMLMeshToUGrid(mesh)
        ugrid = vtk_py.rotateUGrid(ugrid, sx=0.1, sy=0.1, sz=0.1)
        mesh = vtk_py.convertUGridToXMLMesh(ugrid)

    no_of_int_points = 14 * np.shape(mesh.cells())[0]
    print "num_int_points" + str(no_of_int_points)

    facetboundaries = MeshFunction("size_t", mesh, 2)
    edgeboundaries = MeshFunction("size_t", mesh, 1)

    # set surface id numbers:
    topid = 4
    LVendoid = 2
    epiid = 1

    # Define referential facet normal
    N = FacetNormal(mesh)

    # Define spatial coordinate system used in rigid motion constraint
    X = SpatialCoordinate(mesh)

    # ---------  Initialize finite elements  -----------------------------------

    # Vector element at gauss points (for fibers)
    VQuadelem = VectorElement("Quadrature",
                              mesh.ufl_cell(),
                              degree=deg,
                              quad_scheme="default")
    VQuadelem._quad_scheme = 'default'

    # General quadrature element whose points we will evaluate myosim at
    Quadelem = FiniteElement("Quadrature",
                             tetrahedron,
                             degree=deg,
                             quad_scheme="default")
    Quadelem._quad_scheme = 'default'

    # Vector element for displacement
    Velem = VectorElement("CG", mesh.ufl_cell(), 2, quad_scheme="default")
    Velem._quad_scheme = 'default'

    # Quadrature element for pressure
    Qelem = FiniteElement("CG", mesh.ufl_cell(), 1, quad_scheme="default")
    Qelem._quad_scheme = 'default'

    # Real element for rigid body motion boundary condition
    Relem = FiniteElement("Real", mesh.ufl_cell(), 0, quad_scheme="default")
    Relem._quad_scheme = 'default'

    # Mixed element for rigid body motion. One each for x, y displacement. One each for
    # x, y, z rotation
    VRelem = MixedElement([Relem, Relem, Relem, Relem, Relem])

    # ------- Define function spaces on mesh using above elements --------------

    # Quadrature space for information needed at gauss points, such as
    # hsl, cb_force, passive forces, etc.
    Quad = FunctionSpace(mesh, Quadelem)

    # Function space for myosim populations
    Quad_vectorized_Fspace = FunctionSpace(
        mesh, MixedElement(n_array_length * [Quadelem]))

    # Function space for local coordinate system (fiber, sheet, sheet-normal)
    fiberFS = FunctionSpace(mesh, VQuadelem)

    # Mixed function space for displacement, pressure, rigid body constraint
    if (ispressurectrl):
        W = FunctionSpace(mesh, MixedElement([Velem, Qelem, VRelem]))
    else:
        W = FunctionSpace(mesh, MixedElement([Velem, Qelem, Relem, VRelem]))

    # V isn't used? Could define function spaces V: Velem, Q:Qelem,VR: VRelem, then W = V*W*VR
    # but below W is explicitly defined using the elements?
    # could define these once and use them for all projections
    #V = VectorFunctionSpace(mesh, 'CG', 2)
    #TF = TensorFunctionSpace(mesh, 'DG', 1)
    #Q = FunctionSpace(mesh,'CG',1)

    # ------ Initalize functions on above spaces -------------------------------

    # fiber, sheet, and sheet-normal functions
    f0 = Function(fiberFS)
    print f0.vector().array()
    print np.shape(f0.vector())
    #print "free indices of f0 " + str(f0.free_indices())
    s0 = Function(fiberFS)
    n0 = Function(fiberFS)

    # function for original hsl distribution
    hsl0_transmural = Function(Quad)

    # These are now functions because they don't have to be uniform
    c_param = Function(Quad)
    c2_param = Function(Quad)
    c3_param = Function(Quad)

    # Setting the value of the passive functions
    c_param.vector()[:] = passive_params["c"][0]
    c2_param.vector()[:] = passive_params["c2"][0]
    c3_param.vector()[:] = passive_params["c3"][0]

    # Go ahead and read in rest of info from mesh file and close
    # mesh lclee created doesn't have hsl0 variation
    f.read(hsl0_transmural, casename + "/" + "hsl0")
    f.read(f0, casename + "/" + "eF")
    f.read(s0, casename + "/" + "eS")
    f.read(n0, casename + "/" + "eN")

    # read in more mesh info, using MeshFunction for these
    f.read(facetboundaries, casename + "/" + "facetboundaries")
    f.read(edgeboundaries, casename + "/" + "edgeboundaries")

    # finished with the mesh file, close it
    f.close()
    #print f0[0]
    #print np.shape(f0.vector().array())

    # define rest of needed functions
    # mixed function for solver
    w = Function(W)

    # define trial function
    dw = TrialFunction(W)

    # define test function
    wtest = TestFunction(W)

    # separate out individual functions for displacement, pressure, bdry
    if (ispressurectrl):
        du, dp, dc11 = TrialFunctions(W)
        (u, p, c11) = split(w)
        (v, q, v11) = TestFunctions(W)
    else:
        du, dp, dpendo, dc11 = TrialFunctions(W)
        (u, p, pendo, c11) = split(w)
        #(u,p, pendo,c11,lm11) = w.split(True)
        (v, q, qendo, v11) = TestFunctions(W)

    # function for myosim populations
    y_vec = Function(Quad_vectorized_Fspace)

    # not explicitly defined as a function, but product
    #hsl = sqrt(dot(f0, Cmat*f0))*hsl0_transmural

    # Store old hsl and use for calculation of delta_hsl
    hsl_old = Function(Quad)

    # ------- Set up files for saving information -----------------------------

    # save initial mesh information
    File(output_path + "facetboundaries.pvd") << facetboundaries
    File(output_path + "edgeboundaries.pvd") << edgeboundaries
    File(output_path + "fiber.pvd") << project(
        f0, VectorFunctionSpace(mesh, "CG", 1))
    File(output_path + "sheet.pvd") << project(
        s0, VectorFunctionSpace(mesh, "CG", 1))
    File(output_path + "sheet-normal.pvd") << project(
        n0, VectorFunctionSpace(mesh, "CG", 1))

    # Define paraview files to visualize on mesh
    displacementfile = File(output_path + "u_disp.pvd")
    pk1file = File(output_path + "pk1_act_on_f0.pvd")
    hsl_file = File(output_path + "hsl_mesh.pvd")
    alpha_file = File(output_path + "alpha_mesh.pvd")

    # Instead, initialize file for each of these arrays, and append each time step?
    """calcium_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    active_stress_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    myofiber_passive_stress_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    gucc_fiber_pstress_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    gucc_trans_pstress_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    gucc_shear_pstress_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    alpha_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    filament_overlap_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')
    delta_hsl_df = pd.DataFrame(np.zeros((no_of_time_steps+1,no_of_int_points)),dtype='f8')"""

    calcium = np.zeros(no_of_time_steps)
    calcium_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    calcium_ds = calcium_ds.transpose()

    active_stress_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    active_stress_ds = active_stress_ds.transpose()

    dumped_populations_ds = pd.DataFrame(
        np.zeros((no_of_int_points, n_array_length)))

    tarray_ds = pd.DataFrame(np.zeros(no_of_time_steps + 1), index=None)
    tarray_ds = tarray_ds.transpose()
    tarray = np.zeros(no_of_time_steps)

    p_f_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    p_f_array_ds = p_f_array_ds.transpose()

    pgf_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    pgf_array_ds = pgf_array_ds.transpose()

    pgt_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    pgt_array_ds = pgt_array_ds.transpose()

    pgs_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    pgs_array_ds = pgs_array_ds.transpose()

    #overlaparray = np.zeros((no_of_time_steps+1,no_of_int_points)) # need from previous step
    temp_overlap_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    temp_overlap_ds = temp_overlap_ds.transpose()

    alpha_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    alpha_array_ds = alpha_array_ds.transpose()

    hsl_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    hsl_array_ds = hsl_array_ds.transpose()

    delta_hsl_array_ds = pd.DataFrame(np.zeros(no_of_int_points), index=None)
    delta_hsl_array_ds = delta_hsl_array_ds.transpose()

    temp_overlap = np.zeros((no_of_int_points))
    y_vec_array_new = np.zeros(((no_of_int_points) * n_array_length))
    j3_fluxes = np.zeros((no_of_int_points, no_of_time_steps))
    j4_fluxes = np.zeros((no_of_int_points, no_of_time_steps))
    y_interp = np.zeros((no_of_int_points + 1) * n_array_length)

    #test_cbf_storage = pd.Series(np.zeros(no_of_int_points))

    # Saving pressure/volume data
    # define communicator
    comm = mesh.mpi_comm()

    if (MPI.rank(comm) == 0):
        fdataPV = open(output_path + "PV_.txt", "w", 0)
        """hsl_data_file = open(output_path + "hsl_file.txt", "w", 0)
        cbforce_file = open(output_path + "cbforce.txt", "w", 0)
        calcium_data_file = open(output_path + "calcium.txt", "w", 0)
        myosim_fiber_passive_file = open(output_path + "fiber_passive.txt", "w", 0)
        guccione_fiber_pstress_file = open(output_path + "gucc_fiber.txt", "w", 0)
        guccione_trans_pstress_file = open(output_path + "gucc_trans.txt", "w", 0)
        guccione_shear_pstress_file = open(output_path + "gucc_shear.txt", "w", 0)
        alpha_txt_file = open(output_path + "alpha.txt", "w", 0)
        overlap_file = open(output_path + "overlap.txt", "w", 0)"""

    #--------- some miscellaneous definitions ----------------------------------
    isincomp = True  #False

    # initialize LV cavity volume
    LVCavityvol = Expression(("vol"), vol=0.0, degree=2)

    y_vec_array_new = np.zeros(no_of_int_points * n_array_length)

    #Press = Expression(("P"), P=0.0, degree=0)
    #Kspring = Constant(100)

    if (ispressurectrl):
        pendo = []

    # ------- Dirichlet bdry for fixing base in z ------------------------------
    bctop = DirichletBC(
        W.sub(0).sub(2), Expression(("0.0"), degree=2), facetboundaries, topid)
    bcs = [bctop]

    # ------- Set parameters for forms file, where stresses and things are calculated
    params = {
        "mesh": mesh,
        "facetboundaries": facetboundaries,
        "facet_normal": N,
        "mixedfunctionspace": W,
        "mixedfunction": w,
        "displacement_variable": u,
        "pressure_variable": p,
        "lv_volconst_variable": pendo,
        "lv_constrained_vol": LVCavityvol,
        "LVendoid": LVendoid,
        "LVendo_comp": 2,
        "fiber": f0,
        "sheet": s0,
        "sheet-normal": n0,
        "incompressible": isincomp,
        "Kappa": Constant(1e5)
    }

    # Update params from loaded in parameters from json file
    params.update(passive_params)
    params["c"] = c_param
    params["c2"] = c2_param
    params["c3"] = c3_param

    # initialize the forms module
    uflforms = Forms(params)

    # --------- Calculate quantities from form file used in weak form ----------

    LVCavityvol.vol = uflforms.LVcavityvol()
    print("cavity-vol = ", LVCavityvol.vol)

    # Get deformation gradient
    Fmat = uflforms.Fmat()

    # Get right cauchy stretch tensor
    Cmat = (Fmat.T * Fmat)

    # Get Green strain tensor
    Emat = uflforms.Emat()

    # jacobian of deformation gradient
    J = uflforms.J()

    # facet normal in current config
    n = J * inv(Fmat.T) * N

    # integration measure
    dx = dolfin.dx(mesh, metadata={"integration_order": 2})

    # get passive material strain energy function
    Wp = uflforms.PassiveMatSEF()

    #Active force calculation------------------------------------------------------
    # can we move this to the forms file?
    # define 'active_params' as dict and send to forms?
    #hsl = sqrt(dot(f0, Cmat*f0))*hsl0_transmural # must project if want to set directly
    hsl = sqrt(dot(f0, Cmat * f0)) * hsl0
    #f0 = 1/k(U(f0) - f0)
    delta_hsl = hsl - hsl_old
    cb_force = Constant(0.0)
    y_vec_split = split(y_vec)
    print "shape of y_vec_split is " + str(np.shape(y_vec_split))

    for jj in range(no_of_states):

        f_holder = Constant(0.0)

        if state_attached[jj] == 1:

            cb_ext = cb_extensions[jj]

            for k in range(no_of_x_bins):
                temp_holder = Constant(0.0)

                dxx = xx[k] + delta_hsl * filament_compliance_factor

                n_pop = y_vec_split[n_vector_indices[jj][0] + k]

                temp_holder = n_pop * k_cb_multiplier[jj] * (
                    dxx + cb_ext) * conditional(gt(dxx + cb_ext, 0.0),
                                                k_cb_pos, k_cb_neg)
                #temp_holder = temp_holder * conditional(gt(abs(dxx),x_bin_max),0.0,1.0)
                f_holder = f_holder + temp_holder
                #f_holder = f_holder + conditional(gt(temp_holder,0.0),temp_holder,0.0)

            f_holder = f_holder * cb_number_density * 1e-9

            f_holder = f_holder * alpha_value

        cb_force = cb_force + f_holder

    cb_force = cb_force * conditional(gt(cb_force, 0.0), 1.0, 0.0)

    # use cb_force to form active stress tensor
    print np.shape(f0)
    Pactive = cb_force * as_tensor(
        f0[i] * f0[j], (i, j)) + xfiber_fraction * cb_force * as_tensor(
            s0[i] * s0[j], (i, j)) + xfiber_fraction * cb_force * as_tensor(
                n0[i] * n0[j], (i, j))

    # -------- pre-allocation and initialization -------------------------------

    tstep = 0
    #t = 0

    LVcav_array = np.zeros(no_of_time_steps + 1)
    LVcav_array[0] = uflforms.LVcavityvol()
    Pcav_array = np.zeros(no_of_time_steps + 1)
    Pcav_array[0] = uflforms.LVcavitypressure() * 0.0075

    # Contraction phase
    #tarray = []

    # Get array of cross-bridge populations
    y_vec_array = y_vec.vector().get_local()[:]

    hsl_array = project(sqrt(dot(f0, Cmat * f0)) * hsl0,
                        Quad).vector().get_local()[:]

    #delta_hsl_array = np.zeros(no_of_int_points)

    for init_counter in range(0, n_array_length * no_of_int_points,
                              n_array_length):
        # Initializing myosin heads in the off state
        y_vec_array[init_counter] = 1
        # Initialize all binding sites to off state
        y_vec_array[init_counter - 2] = 1

    Pg, Pff, alpha = uflforms.stress()
    # Pg is guccione stress tensor as first Piola-Kirchhoff

    # Magnitude of bulk passive stress in fiber direction
    Pg_fiber = inner(f0, Pg * f0)
    Pg_transverse = inner(n0, Pg * n0)
    Pg_shear = inner(n0, Pg * f0)

    temp_DG = project(Pff,
                      FunctionSpace(mesh, "DG", 1),
                      form_compiler_parameters={"representation": "uflacs"})
    p_f = interpolate(temp_DG, Quad)
    p_f_array = p_f.vector().get_local()[:]

    temp_DG_1 = project(alpha,
                        FunctionSpace(mesh, "DG", 1),
                        form_compiler_parameters={"representation": "uflacs"})
    alphas = interpolate(temp_DG_1, Quad)
    alpha_array = alphas.vector().get_local()[:]

    temp_DG_2 = project(Pg_fiber,
                        FunctionSpace(mesh, "DG", 1),
                        form_compiler_parameters={"representation": "uflacs"})
    pgf = interpolate(temp_DG_2, Quad)
    pgf_array = pgf.vector().get_local()[:]
    temp_DG_3 = project(Pg_transverse,
                        FunctionSpace(mesh, "DG", 1),
                        form_compiler_parameters={"representation": "uflacs"})
    pgt = interpolate(temp_DG_3, Quad)
    pgt_array = pgt.vector().get_local()[:]
    temp_DG_4 = project(Pg_shear,
                        FunctionSpace(mesh, "DG", 1),
                        form_compiler_parameters={"representation": "uflacs"})
    pgs = interpolate(temp_DG_4, Quad)
    pgs_array = pgs.vector().get_local()[:]

    cb_f_array = project(cb_force, Quad).vector().get_local()[:]

    # ------ Define terms for variational problem ------------------------------

    # passive material contribution
    F1 = derivative(Wp, w, wtest) * dx

    # active stress contribution (Pactive is PK1, transform to PK2)
    F2 = inner(Fmat * Pactive, grad(v)) * dx

    # volumetric stress
    if (ispressurectrl):
        pressure = Expression(("p"), p=0.0, degree=2)
        F3 = inner(pressure * n, v) * ds(LVendoid)
    else:
        Wvol = uflforms.LVV0constrainedE()
        F3 = derivative(Wvol, w, wtest)

    # constrain rigid body motion
    L4 = inner(as_vector([c11[0], c11[1], 0.0]), u)*dx + \
      inner(as_vector([0.0, 0.0, c11[2]]), cross(X, u))*dx + \
      inner(as_vector([c11[3], 0.0, 0.0]), cross(X, u))*dx + \
      inner(as_vector([0.0, c11[4], 0.0]), cross(X, u))*dx
    F4 = derivative(L4, w, wtest)

    Ftotal = F1 + F2 + F3 + F4

    Jac1 = derivative(F1, w, dw)
    Jac2 = derivative(F2, w, dw)
    Jac3 = derivative(F3, w, dw)
    Jac4 = derivative(F4, w, dw)

    Jac = Jac1 + Jac2 + Jac3 + Jac4

    # ----- Set up solver, using default but can use LCLee nsolver -------------
    solverparams = {
        "Jacobian": Jac,
        "F": Ftotal,
        "w": w,
        "boundary_conditions": bcs,
        "Type": 0,
        "mesh": mesh,
        "mode": 0
    }

    solver = NSolver(solverparams)

    # -----------------------------

    # Loading phase
    #print "memory growth before loading:"
    #obg.show_growth()

    print("cavity-vol = ", LVCavityvol.vol)
    for lmbda_value in range(0, loading_number):

        print "Loading phase step = ", lmbda_value

        LVCavityvol.vol += 0.004  #LCL change to smaller value

        p_cav = uflforms.LVcavitypressure()
        V_cav = uflforms.LVcavityvol()

        hsl_array_old = hsl_array

        #solver.solvenonlinear()
        solve(Ftotal == 0,
              w,
              bcs,
              J=Jac,
              form_compiler_parameters={"representation": "uflacs"})

        hsl_array = project(hsl, Quad).vector().get_local()[:]  # for Myosim

        temp_DG = project(
            Pff,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        p_f = interpolate(temp_DG, Quad)
        p_f_array = p_f.vector().get_local()[:]

        for ii in range(np.shape(hsl_array)[0]):
            if p_f_array[ii] < 0.0:
                p_f_array[ii] = 0.0

        delta_hsl_array = hsl_array - hsl_array_old

        temp_DG_1 = project(
            alpha,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        alphas = interpolate(temp_DG_1, Quad)
        alpha_array = alphas.vector().get_local()[:]

        temp_DG_2 = project(
            Pg_fiber,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        pgf = interpolate(temp_DG_2, Quad)
        pgf_array = pgf.vector().get_local()[:]
        temp_DG_3 = project(
            Pg_transverse,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        pgt = interpolate(temp_DG_3, Quad)
        pgt_array = pgt.vector().get_local()[:]
        temp_DG_4 = project(
            Pg_shear,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        pgs = interpolate(temp_DG_4, Quad)
        pgs_array = pgs.vector().get_local()[:]

        if (MPI.rank(comm) == 0):

            print >> fdataPV, 0.0, p_cav * 0.0075, 0.0, 0.0, V_cav, 0.0, 0.0, 0.0
            displacementfile << w.sub(0)
            pk1temp = project(inner(f0, Pactive * f0),
                              FunctionSpace(mesh, 'DG', 1))
            pk1temp.rename("pk1temp", "pk1temp")
            pk1file << pk1temp
            hsl_temp = project(hsl, FunctionSpace(mesh, 'DG', 1))
            hsl_temp.rename("hsl_temp", "hsl")
            hsl_file << hsl_temp
            alpha_temp = project(alphas, FunctionSpace(mesh, 'DG', 0))
            alpha_temp.rename("alpha_temp", "alpha_temp")
            alpha_file << alpha_temp

        print("cavity-vol = ", LVCavityvol.vol)
        print("p_cav = ", uflforms.LVcavitypressure())

    # Closed-loop phase

    # Initialize the half-sarcomere class. Its methods will be used to solve for cell populations
    hs = half_sarcomere.half_sarcomere(hs_params, 1)

    # Need to create a list of dictionaries for parameters for each gauss point
    hs_params_list = [{}] * no_of_int_points
    passive_params_list = [{}] * no_of_int_points

    # For now, uniform properties
    for jj in np.arange(np.shape(hs_params_list)[0]):
        hs_params_list[jj] = copy.deepcopy(hs_params)
        passive_params_list[jj] = copy.deepcopy(passive_params)

    # Initialize cell ion module
    cell_ion = cell_ion_driver.cell_ion_driver(cell_ion_params)

    # Initialize calcium
    calcium[0] = cell_ion.calculate_concentrations(0, 0)

    #dumped_populations = np.zeros((no_of_time_steps+1, no_of_int_points, n_array_length))
    dumped_populations = np.zeros((no_of_int_points, n_array_length))

    counter = 0
    cell_counter = 0
    cycle = 0
    AV_old = 0
    MV_old = 1
    systole = 0

    #print "memory growth before closed loop"
    #obg.show_growth()
    while (cycle < cycles):

        p_cav = uflforms.LVcavitypressure()
        V_cav = uflforms.LVcavityvol()

        tstep = tstep + step_size
        cycle = math.floor(tstep / BCL)
        cell_time = tstep - cycle * BCL

        if (MPI.rank(comm) == 0):

            print "Cycle number = ", cycle, " cell time = ", cell_time, " tstep = ", tstep, " step_size = ", step_size
            #print >>fdataPV, tstep, p_cav*0.0075 , V_cav, Myosim.Get_Ca()

        Part = 1.0 / Cao * (V_art - Vart0)
        Pven = 1.0 / Cven * (V_ven - Vven0)
        PLV = p_cav

        if (MPI.rank(comm) == 0):
            print "P_ven = ", Pven
            print "P_LV = ", PLV
            print "P_art = ", Part

        if (PLV <= Part):

            Qao = 0.0
            AV_new = 0

        else:

            Qao = 1.0 / Rao * (PLV - Part)
            AV_new = 1

        if (PLV >= Pven):

            Qmv = 0.0
            MV_new = 0

        else:

            Qmv = 1.0 / Rven * (Pven - PLV)
            MV_new = 1

        Qper = 1.0 / Rper * (Part - Pven)

        if (MV_old == 1 and MV_new == 0):
            systole = 1
        if (AV_old == 1 and AV_new == 0):
            systole = 0

        MV_old = MV_new
        AV_old = AV_new

        if (MPI.rank(comm) == 0):

            print "Q_mv = ", Qmv
            print "Q_ao = ", Qao
            print "Q_per = ", Qper
            if (systole == 1):
                print "********systole**********"
            else:
                print "***diastole***"
        """V_cav_prev = V_cav
        V_art_prev = V_art
        V_ven_prev = V_ven
        p_cav_prev = p_cav"""

        V_cav = V_cav + step_size * (Qmv - Qao)
        V_art = V_art + step_size * (Qao - Qper)
        V_ven = V_ven + step_size * (Qper - Qmv)

        LVCavityvol.vol = V_cav

        if (MPI.rank(comm) == 0):

            print "V_ven = ", V_ven
            print "V_LV = ", V_cav
            print "V_art = ", V_art

        #LVcav_array.append(V_cav)
        LVcav_array[counter] = V_cav
        Pcav_array[counter] = p_cav * 0.0075
        #Pcav_array.append(p_cav*0.0075)

        if (counter > 0 and (int(counter / no_of_cell_time_steps)
                             == (counter / no_of_cell_time_steps))):
            cell_counter = 0

        cell_counter += 1

        print "cell_counter = ", cell_counter
        """for  i in range(no_of_int_points):

            for j in range(n_array_length):

                dumped_populations[counter, i, j] = y_vec_array[i * n_array_length + j]"""

        # Initialize MyoSim solution holder
        #y_vec_array_new = np.zeros(no_of_int_points*n_array_length)

        # Update calcium
        calcium[counter] = cell_ion.calculate_concentrations(
            cycle, tstep)  #LCL Commented off

        # Now print out volumes, pressures, calcium
        if (MPI.rank(comm) == 0):
            print >> fdataPV, tstep, p_cav * 0.0075, Part * .0075, Pven * .0075, V_cav, V_ven, V_art, calcium[
                counter]

        # Quick hack
        if counter == 0:
            overlap_counter = 1
        else:
            overlap_counter = counter
    # Going to try to loop through integration points in python, not in fenics script
    #temp_overlap, y_interp, y_vec_array_new = implement.update_simulation(hs, step_size, delta_hsl_array, hsl_array, y_vec_array, p_f_array, cb_f_array, calcium[counter], n_array_length, cell_time, overlaparray[overlap_counter,:])
    #temp_overlap, y_interp, y_vec_array_new = implement.update_simulation(hs, step_size, delta_hsl_array, hsl_array, y_vec_array, p_f_array, cb_f_array, calcium[counter], n_array_length, cell_time)
        for mm in np.arange(no_of_int_points):
            #print hsl_array[mm]
            temp_overlap[mm], y_interp[mm * n_array_length:(
                mm +
                1) * n_array_length], y_vec_array_new[mm * n_array_length:(
                    mm + 1) * n_array_length] = implement.update_simulation(
                        hs, step_size, delta_hsl_array[mm], hsl_array[mm],
                        y_vec_array[mm * n_array_length:(mm + 1) *
                                    n_array_length], p_f_array[mm],
                        cb_f_array[mm], calcium[counter], n_array_length,
                        tstep, hs_params_list[mm])
        for i in range(no_of_int_points):

            for j in range(n_array_length):

                dumped_populations[i, j] = y_interp[i * n_array_length + j]

        y_vec_array = y_vec_array_new  # for Myosim

        #Kurtis moved to here
        y_vec.vector()[:] = y_vec_array  # for PDE

        hsl_array_old = hsl_array

        #print hsl_array_old
        # Kurtis assigning hsl_old function for newton iteration
        hsl_old.vector()[:] = hsl_array_old[:]

        ###########################################################################

        #solver.solvenonlinear()
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        solve(Ftotal == 0,
              w,
              bcs,
              J=Jac,
              form_compiler_parameters={"representation": "uflacs"})
        """try:
            solve(Ftotal == 0, w, bcs, J = Jac, form_compiler_parameters={"representation":"uflacs"})
        except:
            print "Newton Iteration non-convergence, saving myosim info"
            np.save(output_path +"dumped_populations", dumped_populations)
            np.save(output_path + "tarray", tarray)
            np.save(output_path + "stress_array", strarray)
            np.save(output_path + "hsl", hslarray)
            np.save(output_path + "overlap", overlaparray)
            np.save(output_path + "gucc_fiber", gucc_fiber)
            np.save(output_path + "gucc_trans", gucc_trans)
            np.save(output_path + "gucc_shear", gucc_shear)
            np.save(output_path + "deltahsl", deltahslarray)
            np.save(output_path + "pstress_array",pstrarray)
            #np.save(output_path + "alpha_array",alphaarray)
            np.save(output_path + "calcium",calarray)"""
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        cb_f_array[:] = project(cb_force, Quad).vector().get_local()[:]

        hsl_array = project(hsl, Quad).vector().get_local()[:]  # for Myosim

        delta_hsl_array = hsl_array - hsl_array_old

        temp_DG = project(
            Pff,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        p_f = interpolate(temp_DG, Quad)
        p_f_array = p_f.vector().get_local()[:]

        for ii in range(np.shape(hsl_array)[0]):
            if p_f_array[ii] < 0.0:
                p_f_array[ii] = 0.0

        temp_DG_1 = project(
            alpha,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        alphas = interpolate(temp_DG_1, Quad)
        alpha_array = alphas.vector().get_local()[:]

        temp_DG_2 = project(
            Pg_fiber,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        pgf = interpolate(temp_DG_2, Quad)
        pgf_array = pgf.vector().get_local()[:]
        temp_DG_3 = project(
            Pg_transverse,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        pgt = interpolate(temp_DG_3, Quad)
        pgt_array = pgt.vector().get_local()[:]
        temp_DG_4 = project(
            Pg_shear,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        pgs = interpolate(temp_DG_4, Quad)
        pgs_array = pgs.vector().get_local()[:]

        displacementfile << w.sub(0)
        pk1temp = project(inner(f0, Pactive * f0),
                          FunctionSpace(mesh, 'DG', 1))
        pk1temp.rename("pk1temp", "pk1temp")
        pk1file << pk1temp
        hsl_temp = project(hsl, FunctionSpace(mesh, 'DG', 1))
        hsl_temp.rename("hsl_temp", "hsl")
        hsl_file << hsl_temp
        alpha_temp = project(alphas, FunctionSpace(mesh, 'DG', 0))
        alpha_temp.rename("alpha_temp", "alpha_temp")
        alpha_file << alpha_temp

        print "shape of time array" + str(np.shape(tarray))
        tarray[counter] = tstep
        counter += 1

        if save_output:

            active_stress_ds.iloc[0, :] = cb_f_array[:]
            active_stress_ds.to_csv(output_path + 'active_stress.csv',
                                    mode='a',
                                    header=False)

            #active_stress_ds = active_stress_ds.transpose()
            hsl_array_ds.iloc[0, :] = hsl_array[:]
            hsl_array_ds.to_csv(output_path + 'half_sarcomere_lengths.csv',
                                mode='a',
                                header=False)

            calcium_ds.iloc[0, :] = calcium[counter]
            calcium_ds.to_csv(output_path + 'calcium.csv',
                              mode='a',
                              header=False)

            for i in range(no_of_int_points):
                dumped_populations_ds.iloc[i, :] = dumped_populations[i, :]
            dumped_populations_ds.to_csv(output_path + 'populations.csv',
                                         mode='a',
                                         header=False)

            tarray_ds[counter] = tarray[counter]
            tarray_ds.to_csv(output_path + 'time.csv', mode='a', header=False)

            p_f_array_ds.iloc[0, :] = p_f_array[:]
            p_f_array_ds.to_csv(output_path + 'myofiber_passive.csv',
                                mode='a',
                                header=False)

            pgf_array_ds.iloc[0, :] = pgf_array[:]
            pgf_array_ds.to_csv(output_path + 'gucc_fiber_pstress.csv',
                                mode='a',
                                header=False)

            pgt_array_ds.iloc[0, :] = pgt_array[:]
            pgt_array_ds.to_csv(output_path + 'gucc_trans_pstress.csv',
                                mode='a',
                                header=False)

            pgs_array_ds.iloc[0, :] = pgs_array[:]
            pgs_array_ds.to_csv(output_path + 'gucc_shear_pstress.csv',
                                mode='a',
                                header=False)

            temp_overlap_ds.iloc[0, :] = temp_overlap[:]
            temp_overlap_ds.to_csv(output_path + 'overlap.csv',
                                   mode='a',
                                   header=False)

            alpha_array_ds.iloc[0, :] = alpha_array[:]
            alpha_array_ds.to_csv(output_path + 'alpha.csv',
                                  mode='a',
                                  header=False)

            delta_hsl_array_ds.iloc[0, :] = delta_hsl_array[:]
            delta_hsl_array_ds.to_csv(output_path + 'delta_hsl.csv',
                                      mode='a',
                                      header=False)

        #overlaparray[counter,:] = temp_overlap

    if (MPI.rank(comm) == 0):
        fdataPV.close()
        #fdataCa.close()

    #fluxes, rates = implement.return_rates_fenics(hs)

    # Generate dictionary for output
    """outputs = {
    "rates": rates,
    "dumped_populations": dumped_populations,
    "tarray": tarray,
    "strarray": strarray,
    "pstrarray": pstrarray,
    "gucc_fiber": gucc_fiber,
    "gucc_trans": gucc_trans,
    "gucc_shear": gucc_shear,
    "alphaarray": alphaarray,
    "calarray": calarray,
    "hsl": hslarray,
    "overlap": overlaparray
    }"""

    success = 1
    return (success)
def fenics(sim_params,file_inputs,output_params,passive_params,hs_params,cell_ion_params,monodomain_params,windkessel_params,pso):
    i,j = indices(2)
    m,k = indices(2)

    output_path = output_params["output_path"][0]
    displacementfile = File(output_path + "u_disp.pvd")

    filament_compliance_factor = hs_params["myofilament_parameters"]["filament_compliance_factor"][0]
#    filament_compliance_factor = 0.5

    no_of_states = hs_params["myofilament_parameters"]["num_states"][0]
    #no_of_states = 3
    #no_of_attached_states = 1
    #no_of_detached_states = 2
    no_of_attached_states = hs_params["myofilament_parameters"]["num_attached_states"][0]
    no_of_detached_states = no_of_states-no_of_attached_states
    no_of_transitions = hs_params["myofilament_parameters"]["num_transitions"][0]
    state_attached = hs_params["myofilament_parameters"]["state_attached"][0]
    cb_extensions = hs_params["myofilament_parameters"]["cb_extensions"][0]
    k_cb_multiplier = hs_params["myofilament_parameters"]["k_cb_multiplier"][0]
    k_cb_pos = hs_params["myofilament_parameters"]["k_cb_pos"][0]
    k_cb_neg = hs_params["myofilament_parameters"]["k_cb_neg"][0]
    cb_number_density = hs_params["cb_number_density"][0]
    alpha_value = hs_params["myofilament_parameters"]["alpha"][0]
    x_bin_min = hs_params["myofilament_parameters"]["bin_min"][0]
    x_bin_max = hs_params["myofilament_parameters"]["bin_max"][0]
    x_bin_increment = hs_params["myofilament_parameters"]["bin_width"][0]
    #no_of_transitions = 4
    #state_attached = [0, 0, 1]
    #cb_extensions = [ 0, 0, 4.75642]
    #k_cb_multiplier = [ 1.0, 1.0, 1.0]
    #k_cb_pos = 0.001
    #k_cb_neg = 0.001
    #cb_number_density = 7.67e16
    #alpha_value = 1.0

    #x_bin_min = -12
    #x_bin_max = +12
    #x_bin_increment = 0.5
    xx = np.arange(x_bin_min, x_bin_max + x_bin_increment, x_bin_increment)
    no_of_x_bins = np.shape(xx)[0]
    n_array_length = no_of_attached_states * no_of_x_bins + no_of_detached_states + 2
    n_vector_indices = [[0,0], [1,1], [2,2+no_of_x_bins-1]]

    #hsl0 = 1000
    hsl0 = hs_params["initial_hs_length"][0]
    #time_steps = 401
    #time_steps = 2
    #step_size = 0.5
    step_size = sim_params["sim_timestep"][0]
    sim_duration = sim_params["sim_duration"][0]
    time_steps = int(sim_duration/step_size +1)
    Ca_flag = 4
    constant_pCa = 6.5

    fdataCa = open(output_path + "calcium_.txt", "w", 0)

    fx_rxn = np.zeros((time_steps))

    #prev_ca = np.load("calcium_10.npy")
    #prev_ca = prev_ca[:,0]

    #xml_struct = ut.parse('pm_test10.xml')
    #hs_params = xml_struct.single_circulation_simulation.half_sarcomere
    hs = half_sarcomere.half_sarcomere(hs_params,1)
    cell_ion = cell_ion_driver.cell_ion_driver(cell_ion_params)
    calcium = np.zeros(time_steps)
    calcium[0] = cell_ion.calculate_concentrations(0,0)
    parameters["form_compiler"]["quadrature_degree"]=2
    parameters["form_compiler"]["representation"] = "quadrature"
    #
    #os.system("rm *.pvd")
    #os.system("rm *.vtu")
    # defining parts of the model where the boundary condition should be applied later
    #  where x[0] = 0
    class Left(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]) < tol
    #  where x[0] = 10
    class Right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]-1.0) < tol
    #  where x[2] = 0
    class Lower(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[2]) < tol
    #  where x[1] = 0
    class Front(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[1]) < tol
    #  where x[0], x[1] and x[2] = 0
    class Fix(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]) < tol and abs(x[1]) < tol and abs(x[2]) < tol
    #
    #
    mesh = UnitCubeMesh(1,1,1)
    #mesh.cells()
    no_of_int_points = 4 * np.shape(mesh.cells())[0]

    temp_overlap = np.zeros((no_of_int_points))
    y_vec_array_new = np.zeros(((no_of_int_points)*n_array_length))
    hs_params_list = [{}]*no_of_int_points
    for jj in np.arange(np.shape(hs_params_list)[0]):
        hs_params_list[jj] = copy.deepcopy(hs_params)
    #plot(mesh)
    #plt.show()

    #f0 = Constant((1.0, 0.0, 0.0))
    s0 = Constant((0.0, 1.0, 0.0))
    n0 = Constant((0.0, 0.0, 1.0))

    facetboundaries = MeshFunction('size_t', mesh, mesh.topology().dim()-1)
    facetboundaries.set_all(0)
    left = Left()
    right = Right()
    fix = Fix()
    lower = Lower()
    front = Front()
    #
    left.mark(facetboundaries, 1)
    right.mark(facetboundaries, 2)
    fix.mark(facetboundaries, 3)
    lower.mark(facetboundaries, 4)
    front.mark(facetboundaries, 5)

    File(output_path + "facetboundaries.pvd") << facetboundaries

    #
    ds = dolfin.ds(subdomain_data = facetboundaries)
    #
    ###############################################################################
    #
    #
    isincomp = True#False
    N = FacetNormal (mesh)
    #Cparam = Constant(1.0e2)                                                        #??


    TF = TensorFunctionSpace(mesh, 'DG', 1)

    Velem = VectorElement("Lagrange", tetrahedron, 2, quad_scheme="default")
    Velem._quad_scheme = 'default'
    Qelem = FiniteElement("Lagrange", tetrahedron, 1, quad_scheme="default")
    Qelem._quad_scheme = 'default'
    Quadelem = FiniteElement("Quadrature", tetrahedron, degree=2, quad_scheme="default")
    Quadelem._quad_scheme = 'default'

    # Vector element at gauss points (for fibers)
    VQuadelem = VectorElement("Quadrature", mesh.ufl_cell(), degree=2, quad_scheme="default")
    VQuadelem._quad_scheme = 'default'

    W = FunctionSpace(mesh, MixedElement([Velem,Qelem]))
    x_dofs = W.sub(0).sub(0).dofmap().dofs()

    Quad = FunctionSpace(mesh, Quadelem)

    c_param = Function(Quad)
    c2_param = Function(Quad)
    c3_param = Function(Quad)

    c_param.vector()[:] = passive_params["c"][0]
    c2_param.vector()[:] = passive_params["c2"][0]
    c3_param.vector()[:] = passive_params["c3"][0]

    # Putting them back in the "passive_params" dictionary so that when
    # the dictionary is updated below, it reflects these changes
    passive_params["c"] = c_param
    passive_params["c2"] = c2_param
    passive_params["c3"] = c3_param

    Quad_vectorized_Fspace = FunctionSpace(mesh, MixedElement(n_array_length*[Quadelem]))

    # Assigning initial fiber angles
    fiberFS = FunctionSpace(mesh, VQuadelem)
    f0 = Function(fiberFS)
    #s0 = Function(fiberFS)
    #n0 = Function(fiberFS)

    for i in np.arange(no_of_int_points):
        f0.vector()[i*3] = 1./sqrt(2.)
        #f0.vector()[i*3] = 1.
        #f0.vector()[i*3+1] = 0.
        f0.vector()[i*3+1] = 1./sqrt(2.)
        f0.vector()[i*3+2] = 0.

    File(output_path + "fiber_init.pvd") << project(f0, VectorFunctionSpace(mesh, "DG", 0))


    #print f0.type()

    #f0 = f0/sqrt(inner(f0,f0))


    temp_f = Function(fiberFS)
    f = Function(fiberFS)
    f_diff = Function(fiberFS)
    scaled_fdiff = Function(fiberFS)

    # assigning BCs
    u_D = Expression(("u_D"), u_D = 0.0, degree = 2)
    bcleft= DirichletBC(W.sub(0).sub(0), Constant((0.0)), facetboundaries, 1)         # u1 = 0 on left face
    bcright= DirichletBC(W.sub(0).sub(0), u_D, facetboundaries, 2)
    bcfix = DirichletBC(W.sub(0), Constant((0.0, 0.0, 0.0)), fix, method="pointwise") # at one vertex u = v = w = 0
    bclower= DirichletBC(W.sub(0).sub(2), Constant((0.0)), facetboundaries, 4)        # u3 = 0 on lower face
    bcfront= DirichletBC(W.sub(0).sub(1), Constant((0.0)), facetboundaries, 5)        # u2 = 0 on front face
    bcs = [bcleft, bclower, bcfront, bcright,bcfix]

    du,dp = TrialFunctions(W)
    w = Function(W)
    dw = TrialFunction(W)
    (u,p) = split(w)
    (v,q) = TestFunctions(W)
    wtest = TestFunction(W)

    params= {"mesh": mesh,
         "facetboundaries": facetboundaries,
         "facet_normal": N,
    	 "mixedfunctionspace": W,
    	 "mixedfunction": w,
         "displacement_variable": u,
         "pressure_variable": p,
    	 "fiber": f0,
         "sheet": s0,
         "sheet-normal": n0,
         #"C_param": Cparam,
    	 "incompressible": isincomp,
    	 "Kappa":Constant(1e5)}
    params.update(passive_params)

    uflforms = Forms(params)


    Fmat = uflforms.Fmat()
    Cmat = (Fmat.T*Fmat)
    Emat = uflforms.Emat()
    Umat = uflforms.Umat()
    kappa = 1.0
    J = uflforms.J()


    n = J*inv(Fmat.T)*N
    dx = dolfin.dx(mesh,metadata = {"integration_order":2})

    #Ematrix = project(Emat, TF)
    Wp = uflforms.PassiveMatSEF()

    #Active force calculation------------------------------------------------------
    y_vec = Function(Quad_vectorized_Fspace)
    hsl = sqrt(dot(f0, Cmat*f0))*hsl0
    hsl_old = Function(Quad)
    #hsl_old = hsl
    delta_hsl = hsl - hsl_old
    #delta_hsl = 0.0

    #f_holder = Constant(0.0)
    cb_force = Constant(0.0)

    y_vec_split = split(y_vec)

    for jj in range(no_of_states):

        f_holder = Constant(0.0)
        temp_holder = Constant(0.0)

        if state_attached[jj] == 1:

            cb_ext = cb_extensions[jj]

            for kk in range(no_of_x_bins):

                dxx = xx[kk] + delta_hsl * filament_compliance_factor

                n_pop = y_vec_split[n_vector_indices[jj][0] + kk]

                temp_holder = n_pop * k_cb_multiplier[jj] * (dxx + cb_ext) * conditional(gt(dxx + cb_ext,0.0), k_cb_pos, k_cb_neg)
                #temp_holder = temp_holder*conditional(gt(abs(dxx),x_bin_max),0.0,1.0)
                #f_holder = f_holder + conditional(gt(temp_holder,0.0),temp_holder,0.0)
                f_holder = f_holder + temp_holder

            f_holder = f_holder * cb_number_density * 1e-9

            f_holder = f_holder * alpha_value

        cb_force = cb_force + f_holder

    Pactive = cb_force * as_tensor(f0[m]*f0[k], (m,k))
    Press = Expression(("P"), P=0.0, degree=0)
    # Automatic differentiation  #####################################################################################################
    F1 = derivative(Wp, w, wtest)*dx
    F2 = inner(Fmat*Pactive, grad(v))*dx
    F3 = inner(Press*N, v)*ds(2, domain=mesh)
    Ftotal = F1 + F2 - F3

    Jac1 = derivative(F1, w, dw)
    Jac2 = derivative(F2, w, dw)
    Jac3 = derivative(F3, w, dw)
    Jac = Jac1 + Jac2 - Jac3
    ##################################################################################################################################

    # Contraction phase
    '''header_file = open("./C++/hs.h","r")
    code = header_file.read()
    header_file.close()

    ext_module = compile_extension_module(code=code, source_directory="C++", sources=["hs.cpp", "mf.cpp", "Ca.cpp", "base_parameters.cpp"],
         additional_system_headers=["petscvec.h"],
         include_dirs=[".", os.path.abspath("C++"),"/usr/include", "./C++"],
         library_dirs = ['/usr/lib/x86_64-linux-gnu'],
         libraries = ['libgsl.a'])

    Myosim = ext_module.hs()

    _FE_params = {"step_size": step_size};
    Myosim.FE_params.update(_FE_params)

    _Ca_params = {"Ca_flag": Ca_flag};
    Myosim.Ca_params.update(_Ca_params)

    _Ca_params = {"constant_pCa": constant_pCa};
    Myosim.Ca_params.update(_Ca_params)'''


    darray = []
    tarray = []
    hslarray = np.zeros((time_steps+1,no_of_int_points))
    calarray = []
    strarray = np.zeros((time_steps+1,no_of_int_points))
    pstrarray = np.zeros((time_steps+1,no_of_int_points))
    overlaparray = np.zeros((time_steps+1,no_of_int_points))

    y_vec_array = y_vec.vector().get_local()[:]

    hsl_array = project(hsl, Quad).vector().get_local()[:]

    #hsl_array = np.ones(no_of_int_points)*hsl0
    delta_hsl_array = np.zeros(no_of_int_points)

    for counter in range(0,n_array_length * no_of_int_points,n_array_length):
        #y_vec_array[counter] = 1
        # Starting all in on state for Debugging
        y_vec_array[counter] = 1
        y_vec_array[counter-2] = 1

    Pg, Pff, alpha = uflforms.stress()

    temp_DG = project(Pff, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
    p_f = interpolate(temp_DG, Quad)
    p_f_array = p_f.vector().get_local()[:]

    temp_DG_1 = project(alpha, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
    alphas = interpolate(temp_DG_1, Quad)
    alpha_array = alphas.vector().get_local()[:]

    '''P,S,T = uflforms.stress()
    Pff =  inner(f0,P*f0)
    p_f = project(Pff, Quad)
    p_f_array = p_f.vector().get_local()[:]'''

    #p_f = np.load("/home/fenics/shared/python_dev/test_10/passive_forces.npy")

    cb_f_array = project(cb_force, Quad).vector().get_local()[:]

    dumped_populations = np.zeros((time_steps, no_of_int_points, n_array_length))
    y_interp = np.zeros(no_of_int_points*n_array_length)

    t = 0.0
    #delta_hsls = np.zeros((time_steps,24))
    for l in range(time_steps):



        tarray.append(t)
        for  m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_interp[m * n_array_length + k]

        #hslarray.append(hsl_array[0])
        #strarray.append(cb_f_array[0])
        #pstrarray.append(p_f_array[0])

    #    _Ca_params = {"time_point": l};
    #    Myosim.Ca_params.update(_Ca_params)


        #print p_f[l]

        #for k in range(no_of_int_points):
        #    pop_holder = implement.update_simulation(hs, step_size, delta_hsl_array[k], hsl_array[k], y_vec_array[k*n_array_length:(k+1)*n_array_length],p_f_array[k], cb_f_array[k], prev_ca[l])
    #    y_vec_array_new = Myosim.apply_time_step(y_vec_array, delta_hsl_array, hsl_array, p_f_array, cb_f_array)
        #y_vec_array_new[k*n_array_length:(k+1)*n_array_length] = pop_holder

        # Right now, not general. The calcium depends on cycle number, just saying 0
        cycle = 0
        calcium[l] = cell_ion.calculate_concentrations(step_size,l)

        #calcium[l] = cell_ion.model.calculate_concentrations(0,t)

        # Looping through integration points within Python Myosim, not here
        # Debugging, checking if y_input matches y_output between steps
        #print y_vec_array[0:53]
        # Quick hack
        if l == 0:
            overlap_counter = 1
        else:
            overlap_counter = l

        #temp_overlap, y_interp, y_vec_array_new = implement.update_simulation(hs, step_size, delta_hsl_array, hsl_array, y_vec_array, p_f_array, cb_f_array, calcium[l], n_array_length, t,hs_params_list)
        for mm in np.arange(no_of_int_points):
            #print hsl_array[mm]
            temp_overlap[mm], y_interp[mm*n_array_length:(mm+1)*n_array_length], y_vec_array_new[mm*n_array_length:(mm+1)*n_array_length] = implement.update_simulation(hs, step_size, delta_hsl_array[mm], hsl_array[mm], y_vec_array[mm*n_array_length:(mm+1)*n_array_length], p_f_array[mm], cb_f_array[mm], calcium[l], n_array_length, t,hs_params_list[mm])
    #    print y_vec_array_new[0:53]
        y_vec_array = y_vec_array_new # for Myosim
        y_vec.vector()[:] = y_vec_array # for PDE

    #    print y_vec_array[0:53]
        hsl_array_old = hsl_array


        solve(Ftotal == 0, w, bcs, J = Jac, form_compiler_parameters={"representation":"uflacs"},solver_parameters={"newton_solver":{"relative_tolerance":1e-8},"newton_solver":{"maximum_iterations":50},"newton_solver":{"absolute_tolerance":1e-8}})

        np.save(output_path +"dumped_populations", dumped_populations)
        np.save(output_path + "tarray", tarray)
        np.save(output_path + "stress_array", strarray)
        np.save(output_path + "hsl", hslarray)
        np.save(output_path + "overlap", overlaparray)
        np.save(output_path + "pstress_array",pstrarray)
        #np.save(output_path + "alpha_array",alphaarray)
        np.save(output_path + "calcium",calarray)

        displacementfile << w.sub(0)

        hsl_old.vector()[:] = project(hsl, Quad).vector().get_local()[:] # for PDE

        hsl_array = project(hsl, Quad).vector().get_local()[:]           # for Myosim

        delta_hsl_array = project(sqrt(dot(f0, Cmat*f0))*hsl0, Quad).vector().get_local()[:] - hsl_array_old # for Myosim

        #delta_hsls[l] = delta_hsl_array
        temp_DG = project(Pff, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
        p_f = interpolate(temp_DG, Quad)
        p_f_array = p_f.vector().get_local()[:]

        cb_f_array = project(cb_force, Quad).vector().get_local()[:]
        #strarray.append(cb_f_array[0])
        strarray[l,:] = cb_f_array[:]
        pstrarray[l,:] = p_f_array[:]
        #hslarray.append(hsl_array[0]+delta_hsl_array[0])
        hslarray[l,:] = hsl_array[:] + delta_hsl_array[:]
        overlaparray[l,:] = temp_overlap

        # Calculate reaction force at right end
        b = assemble(Ftotal,form_compiler_parameters={"representation":"uflacs"})
        bcleft.apply(b)

        f_int_total = b.copy()
        for kk in x_dofs:
            fx_rxn[l] += f_int_total[kk]

        np.save(output_path + "fx",fx_rxn)


        #print(cb_f_array)

        """if t <= 100: # stretch to 1300
            u_D.u_D += .003
        if t < 500 and t > 100:
            u_D.u_D =u_D.u_D
        if t < 600 and t >= 500:
            u_D.u_D += .0005
        if t < 800 and t >=600:
            u_D.u_D = u_D.u_D
        if t < 900 and t >= 800:
            u_D.u_D -= .0005
        if t >= 900:
            u_D.u_D = u_D.u_D"""
        """if t < 170 and t > 150:
            u_D.u_D -= 0.005
        else:
            u_D.u_D = u_D.u_D"""
        """if t < 20:
            u_D.u_D += 0.001
        else:
            u_D.u_D = u_D.u_D"""
        if t <= 5.0:
            u_D.u_D = u_D.u_D
        if t > 5.0 and t <= 10.0:
            u_D.u_D += 0.03
        if t > 10.0:
            u_D.u_D = u_D.u_D
        t = t + step_size

        calarray.append(hs.Ca_conc*np.ones(no_of_int_points))

        """for  m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_vec_array[m * n_array_length + k]"""

        #f0 += uflforms.kroon_law(fiberFS)[0] * step_size
        #temp_f = project(Umat*f0,VectorFunctionSpace(mesh,"DG",1),form_compiler_parameters={"representation":"uflacs"})
        #temp_f_2 = interpolate(temp_f, fiberFS)
        temp_f = Umat*f0
        f_mag = sqrt(inner(temp_f,temp_f))
        f = temp_f/f_mag
        f_diff = f-f0
        scaled_fdiff = f_diff * (step_size/kappa)
        scaled_f_assign = project(scaled_fdiff,VectorFunctionSpace(mesh,"DG",1),form_compiler_parameters={"representation":"uflacs"})
        scaled_f_2 = interpolate(scaled_f_assign, fiberFS)
        #print temp_f.type()

        f0.vector()[:] += scaled_f_2.vector()[:]
        File(output_path + "fiber_" + str(l) + ".pvd") << project(f0, VectorFunctionSpace(mesh, "DG", 0))

        #    f0.vector()[abc] += scaled_fdiff.vector()[abc]
        #f0 += scaled_fdiff"""
        #f0 += scaled_fdiff

        #f0 = f0 + new_f_diff*step_size
        #f = Umat*f0/sqrt(inner(Umat*f0,Umat*f0))
        #df0 = (1.0/kappa) * (f - f0)
        #f0 += df0*step_size

    #    File(output_path + "fiber_" + str(t) +".pvd") << project(f0, VectorFunctionSpace(mesh,"CG",1))

    rate_constants = np.zeros((no_of_x_bins,no_of_transitions + 1))

    #for l in range(no_of_x_bins):

    #    for m in range(no_of_transitions + 1):

    #        rate_constants[l,m] = Myosim.dump_rate_constants(l, m, 0)
    fluxes, rates = implement.return_rates_fenics(hs)



    #np.save("/home/fenics/shared/python_dev/test_10_pm/rates",rates)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/dumped_populations",dumped_populations)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/tarray",tarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/stress_array",strarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/pstress_array",p_f)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/calcium",calarray)

    #np.save("/home/fenics/shared/test_10/displacements",darray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/HSL",hslarray)

    #np.save("/home/fenics/shared/test_10/DHSL",delta_hsls)
    outputs = {
    "rates": rates,
    "dumped_populations": dumped_populations,
    "tarray": tarray,
    "strarray": strarray,
    "pstrarray": pstrarray,
    "alphaarray": darray,
    "calarray": calarray,
    "hsl": hslarray,
    "overlap": overlaparray

    }

    np.save(output_path +"dumped_populations", dumped_populations)
    np.save(output_path + "tarray", tarray)
    np.save(output_path + "stress_array", strarray)
    np.save(output_path + "hsl", hslarray)
    np.save(output_path + "overlap", overlaparray)
    np.save(output_path + "pstress_array",pstrarray)
    #np.save(output_path + "alpha_array",alphaarray)
    np.save(output_path + "calcium",calarray)
    fdataCa.close()

    return(outputs)
예제 #3
0
def fenics(sim_params, file_inputs, output_params, passive_params, hs_params,
           cell_ion_params, monodomain_params, windkessel_params):
    global i
    global j

    output_path = output_params["output_path"][0]
    displacementfile = File(output_path + "u_disp.pvd")

    filament_compliance_factor = hs_params["myofilament_parameters"][
        "filament_compliance_factor"][0]
    #    filament_compliance_factor = 0.5

    no_of_states = hs_params["myofilament_parameters"]["num_states"][0]
    #no_of_states = 3
    #no_of_attached_states = 1
    #no_of_detached_states = 2
    no_of_attached_states = hs_params["myofilament_parameters"][
        "num_attached_states"][0]
    no_of_detached_states = no_of_states - no_of_attached_states
    no_of_transitions = hs_params["myofilament_parameters"]["num_transitions"][
        0]
    state_attached = hs_params["myofilament_parameters"]["state_attached"][0]
    cb_extensions = hs_params["myofilament_parameters"]["cb_extensions"][0]
    k_cb_multiplier = hs_params["myofilament_parameters"]["k_cb_multiplier"][0]
    k_cb_pos = hs_params["myofilament_parameters"]["k_cb_pos"][0]
    k_cb_neg = hs_params["myofilament_parameters"]["k_cb_neg"][0]
    cb_number_density = hs_params["cb_number_density"][0]
    alpha_value = hs_params["myofilament_parameters"]["alpha"][0]
    x_bin_min = hs_params["myofilament_parameters"]["bin_min"][0]
    x_bin_max = hs_params["myofilament_parameters"]["bin_max"][0]
    x_bin_increment = hs_params["myofilament_parameters"]["bin_width"][0]
    #no_of_transitions = 4
    #state_attached = [0, 0, 1]
    #cb_extensions = [ 0, 0, 4.75642]
    #k_cb_multiplier = [ 1.0, 1.0, 1.0]
    #k_cb_pos = 0.001
    #k_cb_neg = 0.001
    #cb_number_density = 7.67e16
    #alpha_value = 1.0

    #x_bin_min = -12
    #x_bin_max = +12
    #x_bin_increment = 0.5
    xx = np.arange(x_bin_min, x_bin_max + x_bin_increment, x_bin_increment)
    no_of_x_bins = np.shape(xx)[0]
    n_array_length = no_of_attached_states * no_of_x_bins + no_of_detached_states + 2
    n_vector_indices = [[0, 0], [1, 1], [2, 2 + no_of_x_bins - 1]]

    #hsl0 = 1000
    hsl0 = hs_params["initial_hs_length"][0]
    #time_steps = 401
    #time_steps = 2
    #step_size = 0.5
    step_size = sim_params["sim_timestep"][0]
    sim_duration = sim_params["sim_duration"][0]
    time_steps = int(sim_duration / step_size + 1)
    Ca_flag = 4
    constant_pCa = 6.5

    fdataCa = open(output_path + "calcium_.txt", "w", 0)

    #prev_ca = np.load("calcium_10.npy")
    #prev_ca = prev_ca[:,0]

    #xml_struct = ut.parse('pm_test10.xml')
    #hs_params = xml_struct.single_circulation_simulation.half_sarcomere
    hs = half_sarcomere.half_sarcomere(hs_params, 1)
    cell_ion = cell_ion_driver.cell_ion_driver(cell_ion_params)
    calcium = np.zeros(time_steps)
    calcium[0] = cell_ion.model_class.calculate_concentrations(0, 0)
    parameters["form_compiler"]["quadrature_degree"] = 2
    parameters["form_compiler"]["representation"] = "quadrature"

    #
    #os.system("rm *.pvd")
    #os.system("rm *.vtu")
    # defining parts of the model where the boundary condition should be applied later
    #  where x[0] = 0
    class Left(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]) < tol

    #  where x[0] = 10
    class Right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0] - 10.) < tol

    #  where x[2] = 0
    class FixY(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1e-1
            return near(x[0], 0., tol) and near(x[1], 0., tol)

    class FixZ(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1e-1
            return near(x[0], 0., tol) and near(x[2], 0., tol)

    class FixY_right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1e-1
            return near(x[0], 10., tol) and near(x[1], 0., tol)

    class FixZ_right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1e-1
            return near(x[0], 10., tol) and near(x[2], 0., tol)

    #
    #
    x = 10.0
    y = 0.0
    z = 0.0

    cyl_top = Point(x, y, z)
    cyl_bottom = Point(0, 0, 0)
    top_radius = 1.0
    bottom_radius = 1.0
    segments = 20

    geometry = mshr.Cylinder(cyl_top, cyl_bottom, top_radius, bottom_radius,
                             segments)
    mesh = mshr.generate_mesh(geometry, 30)
    no_of_int_points = 4 * np.shape(mesh.cells())[0]

    #plot(mesh)
    #plt.show()

    VQuadelem = VectorElement("Quadrature",
                              mesh.ufl_cell(),
                              degree=2,
                              quad_scheme="default")
    fiberFS = FunctionSpace(mesh, VQuadelem)

    f0 = Function(fiberFS)
    s0 = Function(fiberFS)
    n0 = Function(fiberFS)

    counter = 0
    """for m in np.arange(np.shape(f0.vector().array())[0]/3):
        m = int(m)
        #f0.vector()[m*3] = np.random.normal(1.,.3)
        f0.vector()[m*3] = np.random.normal(1.,0.0)
        #s0.vector()[m*3] = f0.vector().array()[m*3] - 1.   #sheet vector in plane with fiber vector
        s0.vector()[m*3] = 0.0
        #f0.vector()[m*3+1] = np.random.normal(0.,.3)
        f0.vector()[m*3+1] = np.random.normal(0.,0.0)
        f0.vector()[m*3+2] = 0.0

        #s0.vector()[m*3+1] = f0.vector().array()[m*3+1]
        s0.vector()[m*3+1] = 1.0
        s0.vector()[m*3+2] = 0.0
        n0.vector()[m*3] = 0.0
        n0.vector()[m*3+1] = 0.0
        n0.vector()[m*3+2] = 1.0
        # z component would look like
        # f0.vector()[m*3+2] = something
        # s0.vector()[m*3+2] = f0.vector().array()[int(m)*3+2]
        #n0_holder = np.cross(f0.vector().array()[m*3:m*3+3],s0.vector().array()[m*3:m*3+3])
        #n0_holder /= sqrt(np.inner(n0_holder,n0_holder))

        #for n in range(3):
        #    n0.vector()[m*3+n] = n0_holder[n]
        #s0_holder = np.cross(f0.vector().array()[m*3:m*3+3],n0.vector().array()[m*3:m*3+3])
        #s0_holder /= sqrt(np.inner(s0_holder,s0_holder))
        #for n in range(3):
        #    s0.vector()[m*3+n] = s0_holder[n]
        #f0_holder = f0.vector().array()[m*3:m*3+3]
        #f0_holder /= sqrt(np.inner(f0_holder,f0_holder))
        #for n in range(3):
        #    f0.vector()[m*3+n] = f0_holder[n]"""

    f0 = Constant([1.0, 0.0, 0.0])
    s0 = Constant([0.0, 1.0, 0.0])
    n0 = Constant([0.0, 0.0, 1.0])

    File(output_path + "sheet_normal.pvd") << project(
        n0, VectorFunctionSpace(mesh, "DG", 0))
    File(output_path + "fiber.pvd") << project(
        f0, VectorFunctionSpace(mesh, "CG", 1))
    File(output_path + "sheet.pvd") << project(
        s0, VectorFunctionSpace(mesh, "DG", 0))

    facetboundaries = MeshFunction(
        'size_t', mesh,
        mesh.topology().dim() -
        1)  # fcn that can be evaluated at the mesh entities of 'mesh'
    facetboundaries.set_all(0)  #sets all values in facetboundaries to 0
    left = Left()
    right = Right()
    fixy = FixY()
    fixyright = FixY_right()
    fixzright = FixZ_right()
    fixz = FixZ()
    #
    left.mark(facetboundaries, 1)
    right.mark(facetboundaries, 2)
    fixy.mark(facetboundaries, 3)
    fixz.mark(facetboundaries, 4)
    #
    ds = dolfin.ds(subdomain_data=facetboundaries)
    #
    ###############################################################################
    #
    #
    isincomp = True  #False
    N = FacetNormal(mesh)
    #Cparam = Constant(1.0e2)                                                        #??

    TF = TensorFunctionSpace(mesh, 'DG', 1)

    Velem = VectorElement("Lagrange", tetrahedron, 2, quad_scheme="default")
    Velem._quad_scheme = 'default'
    Qelem = FiniteElement("Lagrange", tetrahedron, 1, quad_scheme="default")
    Qelem._quad_scheme = 'default'
    Quadelem = FiniteElement("Quadrature",
                             tetrahedron,
                             degree=2,
                             quad_scheme="default")
    Quadelem._quad_scheme = 'default'

    W = FunctionSpace(mesh, MixedElement([Velem, Qelem]))
    Quad = FunctionSpace(mesh, Quadelem)

    Quad_vectorized_Fspace = FunctionSpace(
        mesh, MixedElement(n_array_length * [Quadelem]))

    # assigning BCs
    u_D = Expression(("u_D"), u_D=0.0, degree=2)
    # BCs specified for subdomain by index
    bcleft = DirichletBC(W.sub(0), Constant((0, 0, 0)), facetboundaries,
                         1)  # u1 = 0 on left face
    bcright = DirichletBC(W.sub(0), Constant((0, 0, 0)), facetboundaries, 2)
    bcfixy = DirichletBC(W.sub(0).sub(1),
                         Constant((0.)),
                         fixy,
                         method="pointwise")
    bcfixz = DirichletBC(W.sub(0).sub(2),
                         Constant((0.)),
                         fixz,
                         method="pointwise")
    bcfixyright = DirichletBC(W.sub(0).sub(1),
                              Constant((0.)),
                              fixyright,
                              method="pointwise")
    bcfixzright = DirichletBC(W.sub(0).sub(2),
                              Constant((0.)),
                              fixzright,
                              method="pointwise")
    bcs = [bcleft, bcright]

    du, dp = TrialFunctions(W)
    w = Function(W)
    dw = TrialFunction(W)
    (u, p) = split(w)
    (v, q) = TestFunctions(W)
    wtest = TestFunction(W)

    params = {
        "mesh": mesh,
        "facetboundaries": facetboundaries,
        "facet_normal": N,
        "mixedfunctionspace": W,
        "mixedfunction": w,
        "displacement_variable": u,
        "pressure_variable": p,
        "fiber": f0,
        "sheet": s0,
        "sheet-normal": n0,
        #"C_param": Cparam,
        "incompressible": isincomp,
        "Kappa": Constant(1e5)
    }
    params.update(passive_params)

    uflforms = Forms(params)

    Fmat = uflforms.Fmat()
    Cmat = (Fmat.T * Fmat)
    Emat = uflforms.Emat()
    J = uflforms.J()

    n = J * inv(Fmat.T) * N
    dx = dolfin.dx(mesh, metadata={"integration_order": 2})

    #Ematrix = project(Emat, TF)
    Wp = uflforms.PassiveMatSEF()

    #Active force calculation------------------------------------------------------
    y_vec = Function(Quad_vectorized_Fspace)
    hsl = sqrt(dot(f0, Cmat * f0)) * hsl0
    hsl_old = Function(Quad)
    #hsl_old = hsl
    delta_hsl = hsl - hsl_old
    #delta_hsl = 0.0

    #f_holder = Constant(0.0)
    cb_force = Constant(0.0)

    y_vec_split = split(y_vec)

    for jj in range(no_of_states):

        f_holder = Constant(0.0)
        temp_holder = Constant(0.0)

        if state_attached[jj] == 1:

            cb_ext = cb_extensions[jj]

            for kk in range(no_of_x_bins):

                dxx = xx[kk] + delta_hsl * filament_compliance_factor

                n_pop = y_vec_split[n_vector_indices[jj][0] + kk]

                temp_holder = n_pop * k_cb_multiplier[jj] * (
                    dxx + cb_ext) * conditional(gt(dxx + cb_ext, 0.0),
                                                k_cb_pos, k_cb_neg)
                #temp_holder = temp_holder*conditional(gt(abs(dxx),x_bin_max),0.0,1.0)
                #f_holder = f_holder + conditional(gt(temp_holder,0.0),temp_holder,0.0)
                f_holder = f_holder + temp_holder

            f_holder = f_holder * cb_number_density * 1e-9

            f_holder = f_holder * alpha_value

        cb_force = cb_force + f_holder

    Pactive = cb_force * as_tensor(f0[i] * f0[j], (i, j))
    Press = Expression(("P"), P=0.0, degree=0)
    # Automatic differentiation  #####################################################################################################
    F1 = derivative(Wp, w, wtest) * dx
    F2 = inner(Fmat * Pactive, grad(v)) * dx
    F3 = inner(Press * N, v) * ds(2, domain=mesh)
    Ftotal = F1 + F2 - F3

    Jac1 = derivative(F1, w, dw)
    Jac2 = derivative(F2, w, dw)
    Jac3 = derivative(F3, w, dw)
    Jac = Jac1 + Jac2 - Jac3
    ##################################################################################################################################

    # Contraction phase
    '''header_file = open("./C++/hs.h","r")
    code = header_file.read()
    header_file.close()

    ext_module = compile_extension_module(code=code, source_directory="C++", sources=["hs.cpp", "mf.cpp", "Ca.cpp", "base_parameters.cpp"],
         additional_system_headers=["petscvec.h"],
         include_dirs=[".", os.path.abspath("C++"),"/usr/include", "./C++"],
         library_dirs = ['/usr/lib/x86_64-linux-gnu'],
         libraries = ['libgsl.a'])

    Myosim = ext_module.hs()

    _FE_params = {"step_size": step_size};
    Myosim.FE_params.update(_FE_params)

    _Ca_params = {"Ca_flag": Ca_flag};
    Myosim.Ca_params.update(_Ca_params)

    _Ca_params = {"constant_pCa": constant_pCa};
    Myosim.Ca_params.update(_Ca_params)'''

    darray = []
    tarray = []
    hslarray = []
    calarray = []
    strarray = []
    pstrarray = []
    overlaparray = np.zeros((time_steps + 1, no_of_int_points))

    y_vec_array = y_vec.vector().get_local()[:]

    hsl_array = project(hsl, Quad).vector().get_local()[:]

    #hsl_array = np.ones(no_of_int_points)*hsl0
    delta_hsl_array = np.zeros(no_of_int_points)

    for counter in range(0, n_array_length * no_of_int_points, n_array_length):
        #y_vec_array[counter] = 1
        # Starting all in on state for Debugging
        y_vec_array[counter] = 1
        y_vec_array[counter - 2] = 1

    Pg, Pff, alpha = uflforms.stress()

    temp_DG = project(Pff,
                      FunctionSpace(mesh, "DG", 1),
                      form_compiler_parameters={"representation": "uflacs"})
    p_f = interpolate(temp_DG, Quad)
    p_f_array = p_f.vector().get_local()[:]

    temp_DG_1 = project(alpha,
                        FunctionSpace(mesh, "DG", 1),
                        form_compiler_parameters={"representation": "uflacs"})
    alphas = interpolate(temp_DG_1, Quad)
    alpha_array = alphas.vector().get_local()[:]
    '''P,S,T = uflforms.stress()
    Pff =  inner(f0,P*f0)
    p_f = project(Pff, Quad)
    p_f_array = p_f.vector().get_local()[:]'''

    #p_f = np.load("/home/fenics/shared/python_dev/test_10/passive_forces.npy")

    cb_f_array = project(cb_force, Quad).vector().get_local()[:]

    dumped_populations = np.zeros(
        (time_steps, no_of_int_points, n_array_length))
    y_interp = np.zeros(no_of_int_points * n_array_length)
    # Need to create a list of dictionaries for parameters for each gauss point
    hs_params_list = [{}] * no_of_int_points
    temp_overlap = np.zeros((no_of_int_points))
    y_vec_array_new = np.zeros(((no_of_int_points) * n_array_length))

    for jj in np.arange(np.shape(hs_params_list)[0]):
        hs_params_list[jj] = copy.deepcopy(hs_params)
    t = 0.0
    #delta_hsls = np.zeros((time_steps,24))
    for l in range(time_steps):

        tarray.append(t)
        for m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_interp[m * n_array_length + k]

        #hslarray.append(hsl_array[0])
        #strarray.append(cb_f_array[0])
        #pstrarray.append(p_f_array[0])

    #    _Ca_params = {"time_point": l};
    #    Myosim.Ca_params.update(_Ca_params)

    #print p_f[l]

    #for k in range(no_of_int_points):
    #    pop_holder = implement.update_simulation(hs, step_size, delta_hsl_array[k], hsl_array[k], y_vec_array[k*n_array_length:(k+1)*n_array_length],p_f_array[k], cb_f_array[k], prev_ca[l])
    #    y_vec_array_new = Myosim.apply_time_step(y_vec_array, delta_hsl_array, hsl_array, p_f_array, cb_f_array)
    #y_vec_array_new[k*n_array_length:(k+1)*n_array_length] = pop_holder

    # Right now, not general. The calcium depends on cycle number, just saying 0
        cycle = 0
        calcium[l] = cell_ion.model_class.calculate_concentrations(cycle, t)

        #calcium[l] = cell_ion.model.calculate_concentrations(0,t)

        # Looping through integration points within Python Myosim, not here
        # Debugging, checking if y_input matches y_output between steps
        #print y_vec_array[0:53]
        # Quick hack
        if l == 0:
            overlap_counter = 1
        else:
            overlap_counter = l

        for mm in np.arange(no_of_int_points):
            #print hsl_array[mm]
            temp_overlap[mm], y_interp[mm * n_array_length:(
                mm +
                1) * n_array_length], y_vec_array_new[mm * n_array_length:(
                    mm + 1) * n_array_length] = implement.update_simulation(
                        hs, step_size, delta_hsl_array[mm], hsl_array[mm],
                        y_vec_array[mm * n_array_length:(mm + 1) *
                                    n_array_length], p_f_array[mm],
                        cb_f_array[mm], calcium[l], n_array_length, t,
                        overlaparray[overlap_counter, mm], hs_params_list[mm])
        #temp_overlap, y_interp, y_vec_array_new = implement.update_simulation(hs, step_size, delta_hsl_array, hsl_array, y_vec_array, p_f_array, cb_f_array, calcium[l], n_array_length, t,overlaparray[overlap_counter,:])
        #print y_vec_array_new[0:53]
        y_vec_array = y_vec_array_new  # for Myosim
        y_vec.vector()[:] = y_vec_array  # for PDE

        #    print y_vec_array[0:53]
        hsl_array_old = hsl_array

        solve(Ftotal == 0,
              w,
              bcs,
              J=Jac,
              form_compiler_parameters={"representation": "uflacs"},
              solver_parameters={
                  "newton_solver": {
                      "relative_tolerance": 1e-8
                  },
                  "newton_solver": {
                      "maximum_iterations": 50
                  },
                  "newton_solver": {
                      "absolute_tolerance": 1e-8
                  }
              })

        np.save(output_path + "dumped_populations", dumped_populations)
        np.save(output_path + "tarray", tarray)
        np.save(output_path + "stress_array", strarray)
        np.save(output_path + "hsl", hslarray)
        np.save(output_path + "overlap", overlaparray)
        np.save(output_path + "pstress_array", pstrarray)
        #np.save(output_path + "alpha_array",alphaarray)
        np.save(output_path + "calcium", calarray)

        displacementfile << w.sub(0)

        hsl_old.vector()[:] = project(hsl,
                                      Quad).vector().get_local()[:]  # for PDE

        hsl_array = project(hsl, Quad).vector().get_local()[:]  # for Myosim

        delta_hsl_array = project(
            sqrt(dot(f0, Cmat * f0)) * hsl0,
            Quad).vector().get_local()[:] - hsl_array_old  # for Myosim

        #delta_hsls[l] = delta_hsl_array
        temp_DG = project(
            Pff,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        p_f = interpolate(temp_DG, Quad)
        p_f_array = p_f.vector().get_local()[:]

        cb_f_array = project(cb_force, Quad).vector().get_local()[:]
        strarray.append(cb_f_array[0])
        pstrarray.append(p_f_array[0])
        hslarray.append(hsl_array[0] + delta_hsl_array[0])
        overlaparray[l, :] = temp_overlap

        #print(cb_f_array)
        """if t <= 100: # stretch to 1300
            u_D.u_D += .003
        if t < 500 and t > 100:
            u_D.u_D =u_D.u_D
        if t < 600 and t >= 500:
            u_D.u_D += .0005
        if t < 800 and t >=600:
            u_D.u_D = u_D.u_D
        if t < 900 and t >= 800:
            u_D.u_D -= .0005
        if t >= 900:
            u_D.u_D = u_D.u_D"""
        """if t < 170 and t > 150:
            u_D.u_D -= 0.005
        else:
            u_D.u_D = u_D.u_D"""
        u_D.u_D = u_D.u_D
        t = t + step_size

        calarray.append(hs.Ca_conc * np.ones(no_of_int_points))
        """for  m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_vec_array[m * n_array_length + k]"""

    rate_constants = np.zeros((no_of_x_bins, no_of_transitions + 1))

    #for l in range(no_of_x_bins):

    #    for m in range(no_of_transitions + 1):

    #        rate_constants[l,m] = Myosim.dump_rate_constants(l, m, 0)
    fluxes, rates = implement.return_rates_fenics(hs)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/rates",rates)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/dumped_populations",dumped_populations)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/tarray",tarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/stress_array",strarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/pstress_array",p_f)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/calcium",calarray)

    #np.save("/home/fenics/shared/test_10/displacements",darray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/HSL",hslarray)

    #np.save("/home/fenics/shared/test_10/DHSL",delta_hsls)
    outputs = {
        "rates": rates,
        "dumped_populations": dumped_populations,
        "tarray": tarray,
        "strarray": strarray,
        "pstrarray": pstrarray,
        "alphaarray": darray,
        "calarray": calarray,
        "hsl": hslarray,
        "overlap": overlaparray
    }

    np.save(output_path + "dumped_populations", dumped_populations)
    np.save(output_path + "tarray", tarray)
    np.save(output_path + "stress_array", strarray)
    np.save(output_path + "hsl", hslarray)
    np.save(output_path + "overlap", overlaparray)
    np.save(output_path + "pstress_array", pstrarray)
    #np.save(output_path + "alpha_array",alphaarray)
    np.save(output_path + "calcium", calarray)
    fdataCa.close()

    return (outputs)
def fenics(sim_params, file_inputs, output_params, passive_params, hs_params,
           cell_ion_params, monodomain_params, windkessel_params):
    i, j = indices(2)

    output_path = output_params["output_path"][0]
    displacementfile = File(output_path + "u_disp.pvd")

    filament_compliance_factor = hs_params["myofilament_parameters"][
        "filament_compliance_factor"][0]
    #    filament_compliance_factor = 0.5

    no_of_states = hs_params["myofilament_parameters"]["num_states"][0]
    #no_of_states = 3
    #no_of_attached_states = 1
    #no_of_detached_states = 2
    no_of_attached_states = hs_params["myofilament_parameters"][
        "num_attached_states"][0]
    no_of_detached_states = no_of_states - no_of_attached_states
    no_of_transitions = hs_params["myofilament_parameters"]["num_transitions"][
        0]
    state_attached = hs_params["myofilament_parameters"]["state_attached"][0]
    cb_extensions = hs_params["myofilament_parameters"]["cb_extensions"][0]
    k_cb_multiplier = hs_params["myofilament_parameters"]["k_cb_multiplier"][0]
    k_cb_pos = hs_params["myofilament_parameters"]["k_cb_pos"][0]
    k_cb_neg = hs_params["myofilament_parameters"]["k_cb_neg"][0]
    cb_number_density = hs_params["cb_number_density"][0]
    alpha_value = hs_params["myofilament_parameters"]["alpha"][0]
    x_bin_min = hs_params["myofilament_parameters"]["bin_min"][0]
    x_bin_max = hs_params["myofilament_parameters"]["bin_max"][0]
    x_bin_increment = hs_params["myofilament_parameters"]["bin_width"][0]
    #no_of_transitions = 4
    #state_attached = [0, 0, 1]
    #cb_extensions = [ 0, 0, 4.75642]
    #k_cb_multiplier = [ 1.0, 1.0, 1.0]
    #k_cb_pos = 0.001
    #k_cb_neg = 0.001
    #cb_number_density = 7.67e16
    #alpha_value = 1.0

    #x_bin_min = -12
    #x_bin_max = +12
    #x_bin_increment = 0.5
    xx = np.arange(x_bin_min, x_bin_max + x_bin_increment, x_bin_increment)
    no_of_x_bins = np.shape(xx)[0]
    n_array_length = no_of_attached_states * no_of_x_bins + no_of_detached_states + 2
    n_vector_indices = [[0, 0], [1, 1], [2, 2 + no_of_x_bins - 1]]

    #hsl0 = 1000
    hsl0 = hs_params["initial_hs_length"][0]
    #time_steps = 401
    #time_steps = 2
    #step_size = 0.5
    step_size = sim_params["sim_timestep"][0]
    sim_duration = sim_params["sim_duration"][0]
    time_steps = int(sim_duration / step_size + 1)
    Ca_flag = 4
    constant_pCa = 6.5

    fdataCa = open(output_path + "calcium_.txt", "w", 0)

    #prev_ca = np.load("calcium_10.npy")
    #prev_ca = prev_ca[:,0]

    #xml_struct = ut.parse('pm_test10.xml')
    #hs_params = xml_struct.single_circulation_simulation.half_sarcomere
    hs = half_sarcomere.half_sarcomere(hs_params, 1)
    cell_ion = cell_ion_driver.cell_ion_driver(cell_ion_params)
    calcium = np.zeros(time_steps)
    calcium[0] = cell_ion.model_class.calculate_concentrations(0, 0)
    parameters["form_compiler"]["quadrature_degree"] = 2
    parameters["form_compiler"]["representation"] = "quadrature"

    #
    #os.system("rm *.pvd")
    #os.system("rm *.vtu")
    # defining parts of the model where the boundary condition should be applied later
    #  where x[0] = 0
    class Left(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]) < tol

    #  where x[0] = 10
    class Right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0] - 1.0) < tol

    #  where x[2] = 0
    class Lower(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[2]) < tol

    #  where x[1] = 0
    class Front(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[1]) < tol

    #  where x[0], x[1] and x[2] = 0
    class Fix(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]) < tol and abs(x[1]) < tol and abs(
                x[2]) < tol

    #
    #
    mesh = UnitCubeMesh(1, 1, 1)
    #mesh.cells()

    # Vector element at gauss points (for fibers)
    VQuadelem = VectorElement("Quadrature",
                              mesh.ufl_cell(),
                              degree=2,
                              quad_scheme="default")
    VQuadelem._quad_scheme = 'default'

    no_of_int_points = 4 * np.shape(mesh.cells())[0]
    #print no_of_int_points

    #plot(mesh)
    #plt.show()
    # Function space for local coordinate system (fiber, sheet, sheet-normal)

    #f0.vector().array()[:] = [1.0,0.0,0.0]

    #f0 = Constant((1.0, 0.0, 0.0))
    s0 = Constant((0.0, 1.0, 0.0))
    n0 = Constant((0.0, 0.0, 1.0))
    facetboundaries = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    facetboundaries.set_all(0)
    left = Left()
    right = Right()
    fix = Fix()
    lower = Lower()
    front = Front()
    #
    left.mark(facetboundaries, 1)
    right.mark(facetboundaries, 2)
    fix.mark(facetboundaries, 3)
    lower.mark(facetboundaries, 4)
    front.mark(facetboundaries, 5)
    #
    ds = dolfin.ds(subdomain_data=facetboundaries)
    #
    ###############################################################################
    #
    #
    isincomp = True  #False
    N = FacetNormal(mesh)
    #Cparam = Constant(1.0e2)                                                        #??

    TF = TensorFunctionSpace(mesh, 'DG', 1)

    Velem = VectorElement("Lagrange", tetrahedron, 2, quad_scheme="default")
    Velem._quad_scheme = 'default'
    Qelem = FiniteElement("Lagrange", tetrahedron, 1, quad_scheme="default")
    Qelem._quad_scheme = 'default'
    Quadelem = FiniteElement("Quadrature",
                             tetrahedron,
                             degree=2,
                             quad_scheme="default")
    Quadelem._quad_scheme = 'default'

    W = FunctionSpace(mesh, MixedElement([Velem, Qelem]))
    Quad = FunctionSpace(mesh, Quadelem)

    Quad_vectorized_Fspace = FunctionSpace(
        mesh, MixedElement(n_array_length * [Quadelem]))

    # Kurtis trying to initialize vectors
    fiberFS = FunctionSpace(mesh, VQuadelem)
    f0 = Function(fiberFS)

    File(output_path + "fiber1.pvd") << project(
        f0, VectorFunctionSpace(mesh, "CG", 1))

    ugrid = vtk_py.convertXMLMeshToUGrid(mesh)

    File(output_path + "fiber2.pvd") << project(
        f0, VectorFunctionSpace(mesh, "CG", 1))

    gdim = mesh.geometry().dim()
    xdofmap = fiberFS.sub(0).dofmap().dofs()
    ydofmap = fiberFS.sub(1).dofmap().dofs()
    zdofmap = fiberFS.sub(2).dofmap().dofs()

    xq = fiberFS.tabulate_dof_coordinates().reshape((-1, gdim))
    xq0 = xq[xdofmap]
    print "xq0 shape " + str(np.shape(xq0))

    points = vtk.vtkPoints()
    vertices = vtk.vtkCellArray()
    #ugrid = vtk.vtkUnstructuredGrid()

    nb_cells = ugrid.GetNumberOfCells()
    print "num cells = " + str(nb_cells)
    fvecs = vtk_py.createFloatArray("fvecs", 3, 24)

    for i in np.arange(24):
        fvecs.InsertTuple(i, [1.0, 0.0, 0.0])

    cnt = 0

    for pt in xq0:
        points.InsertNextPoint([pt[0], pt[1], pt[2]])
        vertex = vtk.vtkVertex()
        vertex.GetPointIds().SetId(0, cnt)
        vertices.InsertNextCell(vertex)
        cnt += 1

    ugrid.SetPoints(points)
    ugrid.SetCells(0, vertices)

    vtk_py.CreateVertexFromPoint(ugrid)

    #fvecs[:] = f0.vector()[:]
    #ugrid.GetCellData().AddArray(f0.vector())

    ugrid.GetCellData().AddArray(fvecs)
    vtk_py.writeXMLUGrid(ugrid, output_path + "fiber_ugrid.vtu")

    cnt = 0
    for pt in xq0:
        print cnt
        fvec = fvecs.GetTuple(cnt)
        f0.vector()[xdofmap[cnt]] = fvec[0]
        f0.vector()[ydofmap[cnt]] = fvec[1]
        f0.vector()[zdofmap[cnt]] = fvec[2]
        cnt += 1

    mesh = vtk_py.convertUGridToXMLMesh(ugrid)
    """cnt =0

    for pt in xq0:
        print "assigning vector"
        f0.vector()[xdofmap[cnt]] = 1.0*cnt; f0.vector()[ydofmap[cnt]] = 0.0; f0.vector()[zdofmap[cnt]] = 0.0;
        cnt +=1"""

    print f0[0]
    print "shape of f0 " + str(np.shape(f0.vector().array()))

    #print "free indices of f0 " + str(f0.free_indices())

    #f0.vector()[:] = 1.0

    File(output_path + "fiber.pvd") << project(
        f0, VectorFunctionSpace(mesh, "CG", 1))
    #test_tensor = as_tensor(f0*f0)

    # assigning BCs
    u_D = Expression(("u_D"), u_D=0.0, degree=2)
    bcleft = DirichletBC(W.sub(0).sub(0), Constant((0.0)), facetboundaries,
                         1)  # u1 = 0 on left face
    bcright = DirichletBC(W.sub(0).sub(0), u_D, facetboundaries, 2)
    bcfix = DirichletBC(W.sub(0),
                        Constant((0.0, 0.0, 0.0)),
                        fix,
                        method="pointwise")  # at one vertex u = v = w = 0
    bclower = DirichletBC(
        W.sub(0).sub(2), Constant((0.0)), facetboundaries,
        4)  # u3 = 0 on lower face
    bcfront = DirichletBC(
        W.sub(0).sub(1), Constant((0.0)), facetboundaries,
        5)  # u2 = 0 on front face
    bcs = [bcleft, bclower, bcfront, bcright, bcfix]

    du, dp = TrialFunctions(W)
    w = Function(W)
    dw = TrialFunction(W)
    (u, p) = split(w)
    (v, q) = TestFunctions(W)
    wtest = TestFunction(W)

    params = {
        "mesh": mesh,
        "facetboundaries": facetboundaries,
        "facet_normal": N,
        "mixedfunctionspace": W,
        "mixedfunction": w,
        "displacement_variable": u,
        "pressure_variable": p,
        "fiber": f0,
        "sheet": s0,
        "sheet-normal": n0,
        #"C_param": Cparam,
        "incompressible": isincomp,
        "Kappa": Constant(1e5)
    }
    params.update(passive_params)

    uflforms = Forms(params)

    Fmat = uflforms.Fmat()
    Cmat = (Fmat.T * Fmat)
    Emat = uflforms.Emat()
    J = uflforms.J()

    n = J * inv(Fmat.T) * N
    dx = dolfin.dx(mesh, metadata={"integration_order": 2})

    #Ematrix = project(Emat, TF)
    Wp = uflforms.PassiveMatSEF()

    #Active force calculation------------------------------------------------------
    y_vec = Function(Quad_vectorized_Fspace)
    hsl = sqrt(dot(f0, Cmat * f0)) * hsl0
    hsl_old = Function(Quad)
    #hsl_old = hsl
    delta_hsl = hsl - hsl_old
    #delta_hsl = 0.0

    #f_holder = Constant(0.0)
    cb_force = Constant(0.0)

    y_vec_split = split(y_vec)
    print "shape of yvecsplit " + str(np.shape(y_vec_split))

    for jj in range(no_of_states):

        f_holder = Constant(0.0)
        temp_holder = Constant(0.0)

        if state_attached[jj] == 1:

            cb_ext = cb_extensions[jj]

            for kk in range(no_of_x_bins):

                dxx = xx[kk] + delta_hsl * filament_compliance_factor

                n_pop = y_vec_split[n_vector_indices[jj][0] + kk]

                temp_holder = n_pop * k_cb_multiplier[jj] * (
                    dxx + cb_ext) * conditional(gt(dxx + cb_ext, 0.0),
                                                k_cb_pos, k_cb_neg)
                #temp_holder = temp_holder*conditional(gt(abs(dxx),x_bin_max),0.0,1.0)
                #f_holder = f_holder + conditional(gt(temp_holder,0.0),temp_holder,0.0)
                f_holder = f_holder + temp_holder

            f_holder = f_holder * cb_number_density * 1e-9

            f_holder = f_holder * alpha_value

        cb_force = cb_force + f_holder

    #print "rank" + str(f0.rank())
    Pactive = cb_force * as_tensor(s0[i] * s0[j], (i, j))
    Press = Expression(("P"), P=0.0, degree=0)
    # Automatic differentiation  #####################################################################################################
    F1 = derivative(Wp, w, wtest) * dx
    F2 = inner(Fmat * Pactive, grad(v)) * dx
    F3 = inner(Press * N, v) * ds(2, domain=mesh)
    Ftotal = F1 + F2 - F3

    Jac1 = derivative(F1, w, dw)
    Jac2 = derivative(F2, w, dw)
    Jac3 = derivative(F3, w, dw)
    Jac = Jac1 + Jac2 - Jac3
    ##################################################################################################################################

    # Contraction phase
    '''header_file = open("./C++/hs.h","r")
    code = header_file.read()
    header_file.close()

    ext_module = compile_extension_module(code=code, source_directory="C++", sources=["hs.cpp", "mf.cpp", "Ca.cpp", "base_parameters.cpp"],
         additional_system_headers=["petscvec.h"],
         include_dirs=[".", os.path.abspath("C++"),"/usr/include", "./C++"],
         library_dirs = ['/usr/lib/x86_64-linux-gnu'],
         libraries = ['libgsl.a'])

    Myosim = ext_module.hs()

    _FE_params = {"step_size": step_size};
    Myosim.FE_params.update(_FE_params)

    _Ca_params = {"Ca_flag": Ca_flag};
    Myosim.Ca_params.update(_Ca_params)

    _Ca_params = {"constant_pCa": constant_pCa};
    Myosim.Ca_params.update(_Ca_params)'''

    darray = []
    tarray = []
    hslarray = []
    calarray = []
    strarray = []
    pstrarray = []
    overlaparray = np.zeros((time_steps + 1, no_of_int_points))

    y_vec_array = y_vec.vector().get_local()[:]

    hsl_array = project(hsl, Quad).vector().get_local()[:]

    #hsl_array = np.ones(no_of_int_points)*hsl0
    delta_hsl_array = np.zeros(no_of_int_points)

    for counter in range(0, n_array_length * no_of_int_points, n_array_length):
        #y_vec_array[counter] = 1
        # Starting all in on state for Debugging
        y_vec_array[counter] = 1
        y_vec_array[counter - 2] = 1

    Pg, Pff, alpha = uflforms.stress()

    temp_DG = project(Pff,
                      FunctionSpace(mesh, "DG", 1),
                      form_compiler_parameters={"representation": "uflacs"})
    p_f = interpolate(temp_DG, Quad)
    p_f_array = p_f.vector().get_local()[:]

    temp_DG_1 = project(alpha,
                        FunctionSpace(mesh, "DG", 1),
                        form_compiler_parameters={"representation": "uflacs"})
    alphas = interpolate(temp_DG_1, Quad)
    alpha_array = alphas.vector().get_local()[:]
    '''P,S,T = uflforms.stress()
    Pff =  inner(f0,P*f0)
    p_f = project(Pff, Quad)
    p_f_array = p_f.vector().get_local()[:]'''

    #p_f = np.load("/home/fenics/shared/python_dev/test_10/passive_forces.npy")

    cb_f_array = project(cb_force, Quad).vector().get_local()[:]

    dumped_populations = np.zeros(
        (time_steps, no_of_int_points, n_array_length))
    y_interp = np.zeros(no_of_int_points * n_array_length)

    t = 0.0
    #delta_hsls = np.zeros((time_steps,24))
    for l in range(time_steps):

        tarray.append(t)
        for m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_interp[m * n_array_length + k]

        #hslarray.append(hsl_array[0])
        #strarray.append(cb_f_array[0])
        #pstrarray.append(p_f_array[0])

    #    _Ca_params = {"time_point": l};
    #    Myosim.Ca_params.update(_Ca_params)

    #print p_f[l]

    #for k in range(no_of_int_points):
    #    pop_holder = implement.update_simulation(hs, step_size, delta_hsl_array[k], hsl_array[k], y_vec_array[k*n_array_length:(k+1)*n_array_length],p_f_array[k], cb_f_array[k], prev_ca[l])
    #    y_vec_array_new = Myosim.apply_time_step(y_vec_array, delta_hsl_array, hsl_array, p_f_array, cb_f_array)
    #y_vec_array_new[k*n_array_length:(k+1)*n_array_length] = pop_holder

    # Right now, not general. The calcium depends on cycle number, just saying 0
        cycle = 0
        calcium[l] = cell_ion.model_class.calculate_concentrations(cycle, t)

        #calcium[l] = cell_ion.model.calculate_concentrations(0,t)

        # Looping through integration points within Python Myosim, not here
        # Debugging, checking if y_input matches y_output between steps
        #print y_vec_array[0:53]
        # Quick hack
        if l == 0:
            overlap_counter = 1
        else:
            overlap_counter = l

        temp_overlap, y_interp, y_vec_array_new = implement.update_simulation(
            hs, step_size, delta_hsl_array, hsl_array, y_vec_array, p_f_array,
            cb_f_array, calcium[l], n_array_length, t,
            overlaparray[overlap_counter, :])
        #    print y_vec_array_new[0:53]
        y_vec_array = y_vec_array_new  # for Myosim
        y_vec.vector()[:] = y_vec_array  # for PDE

        #    print y_vec_array[0:53]
        hsl_array_old = hsl_array

        solve(Ftotal == 0,
              w,
              bcs,
              J=Jac,
              form_compiler_parameters={"representation": "uflacs"},
              solver_parameters={
                  "newton_solver": {
                      "relative_tolerance": 1e-8
                  },
                  "newton_solver": {
                      "maximum_iterations": 50
                  },
                  "newton_solver": {
                      "absolute_tolerance": 1e-8
                  }
              })

        np.save(output_path + "dumped_populations", dumped_populations)
        np.save(output_path + "tarray", tarray)
        np.save(output_path + "stress_array", strarray)
        np.save(output_path + "hsl", hslarray)
        np.save(output_path + "overlap", overlaparray)
        np.save(output_path + "pstress_array", pstrarray)
        #np.save(output_path + "alpha_array",alphaarray)
        np.save(output_path + "calcium", calarray)

        displacementfile << w.sub(0)

        hsl_old.vector()[:] = project(hsl,
                                      Quad).vector().get_local()[:]  # for PDE

        hsl_array = project(hsl, Quad).vector().get_local()[:]  # for Myosim

        delta_hsl_array = project(
            sqrt(dot(f0, Cmat * f0)) * hsl0,
            Quad).vector().get_local()[:] - hsl_array_old  # for Myosim

        #delta_hsls[l] = delta_hsl_array
        temp_DG = project(
            Pff,
            FunctionSpace(mesh, "DG", 1),
            form_compiler_parameters={"representation": "uflacs"})
        p_f = interpolate(temp_DG, Quad)
        p_f_array = p_f.vector().get_local()[:]

        cb_f_array = project(cb_force, Quad).vector().get_local()[:]
        strarray.append(cb_f_array[0])
        pstrarray.append(p_f_array[0])
        hslarray.append(hsl_array[0] + delta_hsl_array[0])
        overlaparray[l, :] = temp_overlap

        #print(cb_f_array)
        """if t <= 100: # stretch to 1300
            u_D.u_D += .003
        if t < 500 and t > 100:
            u_D.u_D =u_D.u_D
        if t < 600 and t >= 500:
            u_D.u_D += .0005
        if t < 800 and t >=600:
            u_D.u_D = u_D.u_D
        if t < 900 and t >= 800:
            u_D.u_D -= .0005
        if t >= 900:
            u_D.u_D = u_D.u_D"""
        """if t < 170 and t > 150:
            u_D.u_D -= 0.005
        else:
            u_D.u_D = u_D.u_D"""
        if t < 20:
            u_D.u_D += 0.001
        else:
            u_D.u_D = u_D.u_D
        t = t + step_size

        calarray.append(hs.Ca_conc * np.ones(no_of_int_points))

        # Update Fiber orientation
        #f0 = f0+step_size*(Cmat*f0-f0)/sqrt(inner(Cmat*f0-f0,Cmat*f0-f0))
        target_vec = Cmat * f0
        #print target_vec.type()
        #target_diff = target_vec - f0
        #target_diff = target_diff/sqrt(inner(target_diff,target_diff))
        #f0 = f0 + step_size*target_diff
        #File(output_path + "fiber_" +str(t)+ ".pvd") << project(f0, VectorFunctionSpace(mesh, "CG", 1))
        """for  m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_vec_array[m * n_array_length + k]"""

    rate_constants = np.zeros((no_of_x_bins, no_of_transitions + 1))

    #for l in range(no_of_x_bins):

    #    for m in range(no_of_transitions + 1):

    #        rate_constants[l,m] = Myosim.dump_rate_constants(l, m, 0)
    fluxes, rates = implement.return_rates_fenics(hs)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/rates",rates)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/dumped_populations",dumped_populations)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/tarray",tarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/stress_array",strarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/pstress_array",p_f)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/calcium",calarray)

    #np.save("/home/fenics/shared/test_10/displacements",darray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/HSL",hslarray)

    #np.save("/home/fenics/shared/test_10/DHSL",delta_hsls)
    outputs = {
        "rates": rates,
        "dumped_populations": dumped_populations,
        "tarray": tarray,
        "strarray": strarray,
        "pstrarray": pstrarray,
        "alphaarray": darray,
        "calarray": calarray,
        "hsl": hslarray,
        "overlap": overlaparray
    }

    np.save(output_path + "dumped_populations", dumped_populations)
    np.save(output_path + "tarray", tarray)
    np.save(output_path + "stress_array", strarray)
    np.save(output_path + "hsl", hslarray)
    np.save(output_path + "overlap", overlaparray)
    np.save(output_path + "pstress_array", pstrarray)
    #np.save(output_path + "alpha_array",alphaarray)
    np.save(output_path + "calcium", calarray)
    fdataCa.close()

    return (outputs)
예제 #5
0
def fenics(sim_params,file_inputs,output_params,passive_params,hs_params,cell_ion_params,monodomain_params,windkessel_params,pso):

    # marking these as indices because this is a function called from fenics_driver
    i,j = indices(2)

    #------------------## Load in all information and set up simulation --------
    output_path = output_params["output_path"][0]
    displacementfile = File(output_path + "u_disp.pvd")
    save_output = sim_params["save_output"][0]

    filament_compliance_factor = hs_params["myofilament_parameters"]["filament_compliance_factor"][0]
    no_of_states = hs_params["myofilament_parameters"]["num_states"][0]
    no_of_attached_states = hs_params["myofilament_parameters"]["num_attached_states"][0]
    no_of_detached_states = no_of_states-no_of_attached_states
    no_of_transitions = hs_params["myofilament_parameters"]["num_transitions"][0]
    state_attached = hs_params["myofilament_parameters"]["state_attached"][0]
    cb_extensions = hs_params["myofilament_parameters"]["cb_extensions"][0]
    k_cb_multiplier = hs_params["myofilament_parameters"]["k_cb_multiplier"][0]
    k_cb_pos = hs_params["myofilament_parameters"]["k_cb_pos"][0]
    k_cb_neg = hs_params["myofilament_parameters"]["k_cb_neg"][0]
    cb_number_density = hs_params["cb_number_density"][0]
    alpha_value = hs_params["myofilament_parameters"]["alpha"][0]
    x_bin_min = hs_params["myofilament_parameters"]["bin_min"][0]
    x_bin_max = hs_params["myofilament_parameters"]["bin_max"][0]
    x_bin_increment = hs_params["myofilament_parameters"]["bin_width"][0]
    work_loop = sim_params["work_loop"][0]

## ---------  Set up information for active force calculation ------------------

    # Create x interval for cross-bridges
    xx = np.arange(x_bin_min, x_bin_max + x_bin_increment, x_bin_increment)

    # Define number of intervals cross-bridges are defined over
    no_of_x_bins = np.shape(xx)[0]

    # Define the length of the populations vector
    n_array_length = no_of_attached_states * no_of_x_bins + no_of_detached_states + 2
    print "n array length = " + str(n_array_length)
    n_vector_indices = [[0,0], [1,1], [2,2+no_of_x_bins-1]]

    hsl0 = hs_params["initial_hs_length"][0]
    step_size = sim_params["sim_timestep"][0]
    sim_duration = sim_params["sim_duration"][0]
    time_steps = int(sim_duration/step_size +1)
    Ca_flag = 4
    constant_pCa = 6.5

    fdataCa = open(output_path + "calcium_.txt", "w", 0)
    pk1file = File(output_path + "pk1_act_on_f0.pvd")
    hsl_file = File(output_path + "hsl_mesh.pvd")


    # holder for reaction force at right end
    fx_rxn = np.zeros((time_steps))

    shorten_flag = 0 # switches to one if shortening begins

    # Define the cylinder
    x = 10.0
    y = 0.0
    z = 0.0
    cyl_top = Point(x,y,z)
    cyl_bottom = Point(0,0,0)
    top_radius = 1.0
    bottom_radius = 1.0
    segments = 4
    geometry = mshr.Cylinder(cyl_top,cyl_bottom,top_radius,bottom_radius,segments)

    # Create the mesh
    mesh = mshr.generate_mesh(geometry,20)
    # Save the mesh
    File('cylinder_3.pvd') << mesh

    no_of_int_points = 4 * np.shape(mesh.cells())[0]

    # General quadrature element whose points we will evaluate myosim at
    Quadelem = FiniteElement("Quadrature", tetrahedron, degree=2, quad_scheme="default")
    Quadelem._quad_scheme = 'default'

    # Vector element at gauss points (for fibers)
    VQuadelem = VectorElement("Quadrature", mesh.ufl_cell(), degree=2, quad_scheme="default")
    VQuadelem._quad_scheme = 'default'

    # Real element for rigid body motion boundary condition
    Relem = FiniteElement("Real", mesh.ufl_cell(), 0, quad_scheme="default")
    Relem._quad_scheme = 'default'

    # Quadrature space for information needed at gauss points, such as
    # hsl, cb_force, passive forces, etc.
    Quad = FunctionSpace(mesh, Quadelem)

    # Initialize the half-sarcomere class. Its methods will be used to solve for cell populations
    hs = half_sarcomere.half_sarcomere(hs_params,1)

    # Need to create a list of dictionaries for parameters for each gauss point
    hs_params_list = [{}]*no_of_int_points
    passive_params_list = [{}]*no_of_int_points

    # Initialize ion class (get calcium transient from here)
    cell_ion = cell_ion_driver.cell_ion_driver(cell_ion_params)
    calcium = np.zeros(time_steps)
    calcium[0] = cell_ion.calculate_concentrations(0,0)

    for jj in np.arange(np.shape(hs_params_list)[0]):
        hs_params_list[jj] = copy.deepcopy(hs_params)
        passive_params_list[jj] = copy.deepcopy(passive_params)

    # Create a simple expression to test if x_coord is > 9.0
    # making last 10% of cylinder spring elements
    tester = Expression("x[0]",degree=1)
    digitation = Expression("pow(x[1],2) + pow(x[2],2) + 0.5",degree=1)
    point_radius = Expression("sqrt(pow(x[1],2)+pow(x[2],2))",degree=1)

    # Project the expression onto the mesh
    temp_tester_values = project(tester,FunctionSpace(mesh,"DG",1),form_compiler_parameters={"representation":"uflacs"})
    dig_values = project(digitation,FunctionSpace(mesh,"DG",1),form_compiler_parameters={"representation":"uflacs"})
    point_rad_values = project(point_radius,FunctionSpace(mesh,"DG",1),form_compiler_parameters={"representation":"uflacs"})

    # Interpolate onto the FunctionSpace for quadrature points
    temp_tester = interpolate(temp_tester_values,Quad)
    dig = interpolate(dig_values,Quad)
    point_rad = interpolate(point_rad_values,Quad)

    # Create array of the expression values
    temp_tester_array = temp_tester.vector().get_local()
    dig_array = dig.vector().get_local()
    point_rad_array = point_rad.vector().get_local()

    parameters["form_compiler"]["quadrature_degree"]=2
    parameters["form_compiler"]["representation"] = "quadrature"

    # defining parts of the model where the boundary condition should be applied later
    #  where x[0] = 0
    class Left(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]) < tol
    #  where x[0] = 10
    class Right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and abs(x[0]-10.0) < tol
    class Fix_y(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-1
            return near(x[0],0.0,tol) and near(x[1],0.0,tol)
    class Fix_y_right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return near(x[0],10.0,tol) and near(x[1],0.0,tol)
    class Fix_z_right(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return near(x[0],10.0,tol) and near(x[2],0.0,tol)
    class Fix_z(SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return (near(x[0],0.0,tol) and near(x[2],0.0,tol))




    # now test_marker_fcn has value of 1 on right boundary always


    # Define spatial coordinate system used in rigid motion constraint
    X = SpatialCoordinate (mesh)
    facetboundaries = MeshFunction('size_t', mesh, mesh.topology().dim()-1)
    edgeboundaries = MeshFunction('size_t', mesh, mesh.topology().dim()-2)

    facetboundaries.set_all(0)
    left = Left()
    right = Right()
    fix_y = Fix_y()
    fix_y_right = Fix_y_right()
    fix_z = Fix_z()
    fix_z_right = Fix_z_right()
    #horizontal = Horizontal()
    #lower = Lower()
    #front = Front()
    #
    left.mark(facetboundaries, 1)
    right.mark(facetboundaries, 2)
    fix_y.mark(facetboundaries, 3)
    #horizontal.mark(facetboundaries,4)
    fix_z.mark(facetboundaries,5)

    marker_space = FunctionSpace(mesh,'CG',1)
    bc_right_test = DirichletBC(marker_space,Constant(1),facetboundaries,2)
    test_marker_fcn = Function(marker_space)
    bc_right_test.apply(test_marker_fcn.vector())

    File(output_path + "facetboundaries.pvd") << facetboundaries

    #lower.mark(facetboundaries, 4)
    #front.mark(facetboundaries, 5)
    #
    ds = dolfin.ds(subdomain_data = facetboundaries)

    #
    ###############################################################################
    isincomp = True#False
    N = FacetNormal (mesh)
    #Cparam = Constant(1.0e2)


    TF = TensorFunctionSpace(mesh, 'DG', 1)

    Velem = VectorElement("Lagrange", tetrahedron, 2, quad_scheme="default")
    Velem._quad_scheme = 'default'
    Qelem = FiniteElement("Lagrange", tetrahedron, 1, quad_scheme="default")
    Qelem._quad_scheme = 'default'
    # Mixed element for rigid body motion. One each for x, y displacement. One each for
    # x, y, z rotation
    VRelem = MixedElement([Relem, Relem, Relem, Relem, Relem])


    W = FunctionSpace(mesh, MixedElement([Velem,Qelem,VRelem]))
    x_dofs = W.sub(0).sub(0).dofmap().dofs()

    Quad_vectorized_Fspace = FunctionSpace(mesh, MixedElement(n_array_length*[Quadelem]))


    # Kurtis trying to initialize vectors
    fiberFS = FunctionSpace(mesh, VQuadelem)
    f0 = Function(fiberFS)
    s0 = Function(fiberFS)
    n0 = Function(fiberFS)
    f0_diff = Function(fiberFS)

    c_param = Function(Quad)
    c2_param = Function(Quad)
    c3_param = Function(Quad)

    File(output_path + "fiber1.pvd") << project(f0, VectorFunctionSpace(mesh, "DG", 0))

    m_x = 1.0
    m_y = 0.0
    m_z = 0.0
    width = sim_params["width"][0]
    #x_comps = r.normal(m_x,width,no_of_int_points)
    #y_comps = r.normal(m_y,width,no_of_int_points)
    #z_comps = r.normal(m_z,width,no_of_int_points)
    for jj in np.arange(no_of_int_points):

        #if (temp_tester_array[jj] < dig_array[jj]) or (temp_tester_array[jj] > -dig_array[jj] + 10.0):
        if (temp_tester_array[jj] > 9.0) or (temp_tester_array[jj] < 1.0):
            # inside left end
            f0.vector()[jj*3] = 1.0
            f0.vector()[jj*3+1] = 0.0
            f0.vector()[jj*3+2] = 0.0
            hs_params_list[jj]["myofilament_parameters"]["k_3"][0] = 0.0
            #passive_params_list[jj]["c"][0] = 2000
            c_param.vector()[jj] = 400
            c2_param.vector()[jj] = 250
            c3_param.vector()[jj] = 10


        else:

            # In middle region, assign fiber vector
            # find radius of point
            temp_radius = point_rad_array[jj]
            if np.abs(temp_radius - top_radius) < 0.01:
                temp_width = 0.0
            else:
                temp_width = width*(1.0-(temp_radius*temp_radius/(top_radius*top_radius)))
            f0.vector()[jj*3] = r.normal(m_x,temp_width,1)[0]
            f0.vector()[jj*3+1] = r.normal(m_y,temp_width,1)[0]
            f0.vector()[jj*3+2] = r.normal(m_z,temp_width,1)[0]
            c_param.vector()[jj] = 1000
            c2_param.vector()[jj] = 250
            c3_param.vector()[jj] = 15
        """f0.vector()[kk*3] = x_comps[kk]
        # assign y component
        f0.vector()[kk*3+1] = y_comps[kk]
        # z component would look like
        f0.vector()[kk*3+2] = z_comps[kk]"""

    f0 = f0/sqrt(inner(f0,f0))

    #f0_norm = project(sqrt(inner(f0,f0)),FunctionSpace(mesh,"CG",1))
    #print "norm is " + str(f0_norm.vector().array())
    #stop

    f0_diff = f0 - Constant((1.,0.,0.))
    long_axis = Function(fiberFS)

    for nn in np.arange(no_of_int_points):
        long_axis.vector()[nn*3] = 0.0
        long_axis.vector()[nn*3+1] = 0.0
        long_axis.vector()[nn*3+2] = 1.0

    #s0 = f0 + f0_diff # sum object
    #n0 = cross(f0,s0) # cross object

    #s0  = project(Constant((0,1,0))+f0_diff,VectorFunctionSpace(mesh, "DG", 0))
    s0 = cross(long_axis,f0)
    s0 = s0/sqrt(inner(s0,s0))
    File(output_path + "sheet.pvd") << project(s0,VectorFunctionSpace(mesh, "DG", 0))

    n0 = project(cross(f0,s0),VectorFunctionSpace(mesh, "DG", 0))
    n0 = n0/sqrt(inner(n0,n0))
    File(output_path + "sheet_normal.pvd") << project(n0,VectorFunctionSpace(mesh, "DG", 0))
    File(output_path + "fiber.pvd") << project(f0, VectorFunctionSpace(mesh, "CG", 1))
    #test_tensor = as_tensor(f0*f0)

    # assigning BCs
    u_D = Expression(("u_D"), u_D = 0.0, degree = 2)
    bcleft= DirichletBC(W.sub(0).sub(0), Constant((0.0)), facetboundaries, 1)         # u1 = 0 on left face
    bcright= DirichletBC(W.sub(0).sub(0), u_D, facetboundaries, 2)
    bcfix_y = DirichletBC(W.sub(0).sub(1), Constant((0.0)), fix_y, method="pointwise")
    bcfix_z = DirichletBC(W.sub(0).sub(2), Constant((0.0)), fix_z, method="pointwise") # at one vertex u = v = w = 0
    bcfix_y_right = DirichletBC(W.sub(0).sub(1), Constant((0.0)),fix_y_right, method="pointwise")
    bcfix_z_right = DirichletBC(W.sub(0).sub(2), Constant((0.0)),fix_z_right, method="pointwise")
    #bchorizontal = DirichletBC(W.sub(0).sub(1), Constant((0.0)), horizontal, method="pointwise")
    #bclower= DirichletBC(W.sub(0).sub(2), Constant((0.0)), facetboundaries, 4)        # u3 = 0 on lower face
    #bcfront= DirichletBC(W.sub(0).sub(1), Constant((0.0)), facetboundaries, 5)        # u2 = 0 on front face
    #bcs = [bcleft, bclower, bcfront, bcright,bcfix]

    bcs = [bcleft, bcright,bcfix_y,bcfix_z,bcfix_y_right,bcfix_z_right]

    du,dp,dc11 = TrialFunctions(W)
    w = Function(W)
    dw = TrialFunction(W)
    (u,p,c11) = split(w)
    (v,q,v11) = TestFunctions(W)
    wtest = TestFunction(W)

    params= {"mesh": mesh,
         "facetboundaries": facetboundaries,
         "facet_normal": N,
    	 "mixedfunctionspace": W,
    	 "mixedfunction": w,
         "displacement_variable": u,
         "pressure_variable": p,
    	 "fiber": f0,
         "sheet": s0,
         "sheet-normal": n0,
         #"C_param": Cparam,
    	 "incompressible": isincomp,
    	 "Kappa":Constant(1e5)}
    params.update(passive_params)
    params["c"] = c_param
    params["c2"] = c2_param
    params["c3"] = c3_param

    uflforms = Forms(params)


    Fmat = uflforms.Fmat()
    Cmat = (Fmat.T*Fmat)
    Emat = uflforms.Emat()
    J = uflforms.J()

    n = J*inv(Fmat.T)*N
    dx = dolfin.dx(mesh,metadata = {"integration_order":2})

    #Ematrix = project(Emat, TF)
    Wp = uflforms.PassiveMatSEF()

    #Active force calculation------------------------------------------------------
    y_vec = Function(Quad_vectorized_Fspace)
    hsl = sqrt(dot(f0, Cmat*f0))*hsl0
    hsl_old = Function(Quad)
    #hsl_old = hsl
    delta_hsl = hsl - hsl_old
    #delta_hsl = 0.0

    #f_holder = Constant(0.0)
    cb_force = Constant(0.0)

    y_vec_split = split(y_vec)
    #print "shape of yvecsplit " + str(np.shape(y_vec_split))

    for jj in range(no_of_states):

        f_holder = Constant(0.0)
        temp_holder = Constant(0.0)

        if state_attached[jj] == 1:

            cb_ext = cb_extensions[jj]

            for kk in range(no_of_x_bins):

                dxx = xx[kk] + delta_hsl * filament_compliance_factor

                n_pop = y_vec_split[n_vector_indices[jj][0] + kk]

                temp_holder = n_pop * k_cb_multiplier[jj] * (dxx + cb_ext) * conditional(gt(dxx + cb_ext,0.0), k_cb_pos, k_cb_neg)
                #temp_holder = temp_holder*conditional(gt(abs(dxx),x_bin_max),0.0,1.0)
                #f_holder = f_holder + conditional(gt(temp_holder,0.0),temp_holder,0.0)
                f_holder = f_holder + temp_holder

            f_holder = f_holder * cb_number_density * 1e-9

            f_holder = f_holder * alpha_value

        cb_force = cb_force + f_holder

    #print "rank" + str(f0.rank())
    Pactive = cb_force * as_tensor(f0[i]*f0[j], (i,j))
    Press = Expression(("P"), P=0.0, degree=0)
    # Automatic differentiation  #####################################################################################################
    F1 = derivative(Wp, w, wtest)*dx
    F2 = inner(Fmat*Pactive, grad(v))*dx
    F3 = inner(Press*N, v)*ds(2, domain=mesh)
    # constrain rigid body motion
    """L4 = inner(as_vector([c11[0], c11[1], 0.0]), u)*dx + \
    	 inner(as_vector([0.0, 0.0, c11[2]]), cross(X, u))*dx + \
    	 inner(as_vector([c11[3], 0.0, 0.0]), cross(X, u))*dx + \
    	 inner(as_vector([0.0, c11[4], 0.0]), cross(X, u))*dx
    F4 = derivative(L4, w, wtest)"""
    Ftotal = F1 + F2 - F3 #+ F4

    Jac1 = derivative(F1, w, dw)
    Jac2 = derivative(F2, w, dw)
    Jac3 = derivative(F3, w, dw)
    #Jac4 = derivative(F4, w, dw)
    Jac = Jac1 + Jac2 - Jac3 #+ Jac4
    ##################################################################################################################################


    darray = []
    """hslarray = np.zeros((time_steps+1,no_of_int_points))
    calarray = []
    strarray = np.zeros((time_steps+1,no_of_int_points))
    pstrarray = np.zeros((time_steps+1,no_of_int_points))
    overlaparray = np.zeros((time_steps+1,no_of_int_points))"""

    calcium_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    calcium_ds = calcium_ds.transpose()
    calcium = np.zeros(time_steps)

    active_stress_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    active_stress_ds = active_stress_ds.transpose()

    dumped_populations_ds = pd.DataFrame(np.zeros((no_of_int_points,n_array_length)))

    tarray_ds = pd.DataFrame(np.zeros(time_steps+1),index=None)
    tarray_ds = tarray_ds.transpose()
    tarray = np.zeros(time_steps)

    p_f_array_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    p_f_array_ds = p_f_array_ds.transpose()

    pgf_array_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    pgf_array_ds = pgf_array_ds.transpose()

    pgt_array_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    pgt_array_ds = pgt_array_ds.transpose()

    pgs_array_ds =pd.DataFrame(np.zeros(no_of_int_points),index=None)
    pgs_array_ds = pgs_array_ds.transpose()

    temp_overlap_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    temp_overlap_ds = temp_overlap_ds.transpose()

    alpha_array_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    alpha_array_ds = alpha_array_ds.transpose()

    hsl_array_ds =pd.DataFrame(np.zeros(no_of_int_points),index=None)
    hsl_array_ds = hsl_array_ds.transpose()

    delta_hsl_array_ds = pd.DataFrame(np.zeros(no_of_int_points),index=None)
    delta_hsl_array_ds = delta_hsl_array_ds.transpose()

    y_vec_array = y_vec.vector().get_local()[:]

    hsl_array = project(hsl, Quad).vector().get_local()[:]

    #hsl_array = np.ones(no_of_int_points)*hsl0
    delta_hsl_array = np.zeros(no_of_int_points)

    for counter in range(0,n_array_length * no_of_int_points,n_array_length):
        y_vec_array[counter] = 1
        y_vec_array[counter-2] = 1

    Pg, Pff, alpha = uflforms.stress()

    # Magnitude of bulk passive stress in fiber direction
    Pg_fiber = inner(f0,Pg*f0)
    Pg_transverse = inner(n0,Pg*n0)
    Pg_shear = inner(n0,Pg*f0)

    temp_DG = project(Pff, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
    p_f = interpolate(temp_DG, Quad)
    p_f_array = p_f.vector().get_local()[:]

    temp_DG_1 = project(alpha, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
    alphas = interpolate(temp_DG_1, Quad)
    alpha_array = alphas.vector().get_local()[:]

    cb_f_array = project(cb_force, Quad).vector().get_local()[:]

    dumped_populations = np.zeros((no_of_int_points, n_array_length))
    y_interp = np.zeros((no_of_int_points)*n_array_length)

    x_dofs = W.sub(0).sub(0).dofmap().dofs()

    temp_overlap = np.zeros((no_of_int_points))
    y_vec_array_new = np.zeros(((no_of_int_points)*n_array_length))
    j3_fluxes = np.zeros((no_of_int_points,time_steps))
    j4_fluxes = np.zeros((no_of_int_points,time_steps))
    #print "shapes of stuff"
    #print np.shape(temp_overlap)
    #print np.shape(y_vec_array_new)
    temp_astress = np.ones(no_of_int_points)
    t = 0.0
    #delta_hsls = np.zeros((time_steps,24))
    for l in range(time_steps):



        tarray[l]=(t)





        # Right now, not general. The calcium depends on cycle number, just saying 0
        cycle = 0
        #calcium[l] = cell_ion.model_class.calculate_concentrations(cycle,t)
        calcium[l] = cell_ion.calculate_concentrations(step_size,l)

        #calcium[l] = cell_ion.model.calculate_concentrations(0,t)

        # Looping through integration points within Python Myosim, not here

        # Quick hack
        if l == 0:
            overlap_counter = 1
        else:
            overlap_counter = l

        # Because we want to be able to change contractility parameters for each
        # gauss point, we need to loop through the gauss points here

        #temp_overlap, y_interp, y_vec_array_new = implement.update_simulation(hs, step_size, delta_hsl_array, hsl_array, y_vec_array, p_f_array, cb_f_array, calcium[l], n_array_length, t,overlaparray[overlap_counter,:])
        #print "hs list dict " + str(hs_params_list
        #print "y_vec_new " + str(y_vec_array_new)
        for mm in np.arange(no_of_int_points):
            #print hsl_array[mm]
            temp_overlap[mm], y_interp[mm*n_array_length:(mm+1)*n_array_length], y_vec_array_new[mm*n_array_length:(mm+1)*n_array_length] = implement.update_simulation(hs, step_size, delta_hsl_array[mm], hsl_array[mm], y_vec_array[mm*n_array_length:(mm+1)*n_array_length], p_f_array[mm], cb_f_array[mm], calcium[l], n_array_length, t,hs_params_list[mm])
            temp_flux_dict, temp_rate_dict = implement.return_rates_fenics(hs)
            #print temp_flux_dict["J3"]
            j3_fluxes[mm,l] = sum(temp_flux_dict["J3"])
            j4_fluxes[mm,l] = sum(temp_flux_dict["J4"])
    #    print y_vec_array_new[0:53]
        y_vec_array = y_vec_array_new # for Myosim
        print " num gauss points " + str(no_of_int_points)
        print "y_vec shape" + str(np.shape(y_vec_array))
        print "y_interp shape"  + str(np.shape(y_interp))

        for  m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[m, k] = y_interp[m * n_array_length + k]


        #print "shapes of stuff"
        #print np.shape(y_vec.vector())
        #print np.shape(y_vec_array)
        y_vec.vector()[:] = y_vec_array # for PDE

    #    print y_vec_array[0:53]
        hsl_array_old = hsl_array

        # trying to implement a work loop

        if work_loop:

            if l>0:
                temp_astress = cb_f_array[:]
                temp_astress = temp_astress[temp_astress > 0.0]
                if np.shape(temp_astress)[0] == 0:
                    temp_astress=0.0
            """if l > 2:
                u_check = project(u,VectorFunctionSpace(mesh,"CG",2))
                disp_value = u_check.vector()[test_marker_fcn.vector()==1]
                print "displacement after shortening on right is = " + str(disp_value[0])
                u_D.u_D=disp_value[0]"""
            if np.average(temp_astress>=50000):
                Press.P=50000
                bcs = [bcleft,bcfix_y,bcfix_z,bcfix_y_right,bcfix_z_right]
                shorten_flag = 1
            else:
                if shorten_flag < 0:
                    u_D.u_D = u_D.u_D
                    Press.P=0.0

                if shorten_flag > 0:
                    u_check = project(u,VectorFunctionSpace(mesh,"CG",2))
                    disp_value = u_check.vector()[test_marker_fcn.vector()==1]
                    print "displacement after shortening on right is = " + str(disp_value[0])
                    u_D.u_D=disp_value[0]
                    shorten_flag = -1

                bcs = [bcleft,bcright,bcfix_y,bcfix_z,bcfix_y_right,bcfix_z_right]



        solve(Ftotal == 0, w, bcs, J = Jac, form_compiler_parameters={"representation":"uflacs"},solver_parameters={"newton_solver":{"relative_tolerance":1e-8},"newton_solver":{"maximum_iterations":50},"newton_solver":{"absolute_tolerance":1e-8}})

        """np.save(output_path +"dumped_populations", dumped_populations)
        np.save(output_path + "tarray", tarray)
        np.save(output_path + "stress_array", strarray)
        np.save(output_path + "hsl", hslarray)
        np.save(output_path + "overlap", overlaparray)
        np.save(output_path + "pstress_array",pstrarray)
        #np.save(output_path + "alpha_array",alphaarray)
        np.save(output_path + "calcium",calarray)"""

        displacementfile << w.sub(0)
        pk1temp = project(inner(f0,Pactive*f0),FunctionSpace(mesh,'CG',1))
        pk1temp.rename("pk1temp","pk1temp")
        pk1file << pk1temp
        hsl_temp = project(hsl,FunctionSpace(mesh,'DG',1))
        hsl_temp.rename("hsl_temp","hsl")
        #hsl_file << hsl_temp

        hsl_old.vector()[:] = project(hsl, Quad).vector().get_local()[:] # for PDE

        hsl_array = project(hsl, Quad).vector().get_local()[:]           # for Myosim

        delta_hsl_array = project(sqrt(dot(f0, Cmat*f0))*hsl0, Quad).vector().get_local()[:] - hsl_array_old # for Myosim

        #delta_hsls[l] = delta_hsl_array
        temp_DG = project(Pff, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
        p_f = interpolate(temp_DG, Quad)
        p_f_array = p_f.vector().get_local()[:]

        for ii in range(np.shape(hsl_array)[0]):
            if p_f_array[ii] < 0.0:
                p_f_array[ii] = 0.0

        temp_DG_2 = project(Pg_fiber, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
        pgf = interpolate(temp_DG_2, Quad)
        pgf_array = pgf.vector().get_local()[:]
        temp_DG_3 = project(Pg_transverse, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
        pgt = interpolate(temp_DG_3, Quad)
        pgt_array = pgt.vector().get_local()[:]
        temp_DG_4 = project(Pg_shear, FunctionSpace(mesh, "DG", 1), form_compiler_parameters={"representation":"uflacs"})
        pgs = interpolate(temp_DG_4, Quad)
        pgs_array = pgs.vector().get_local()[:]

        cb_f_array = project(cb_force, Quad).vector().get_local()[:]
        #strarray.append(cb_f_array[0])
        #strarray[l,:] = cb_f_array[:]
        #pstrarray[l,:] = p_f_array[:]
        #hslarray.append(hsl_array[0]+delta_hsl_array[0])
        #hslarray[l,:] = hsl_array[:] + delta_hsl_array[:]
        #overlaparray[l,:] = temp_overlap

        # Calculate reaction force at right end
        b = assemble(Ftotal,form_compiler_parameters={"representation":"uflacs"})
        bcleft.apply(b)
        bcfix_y.apply(b)
        bcfix_z.apply(b)
        bcfix_y_right.apply(b)
        bcfix_z_right.apply(b)

        f_int_total = b.copy()
        for kk in x_dofs:
            fx_rxn[l] += f_int_total[kk]
        #bcleft.apply(f_int_total)
        #FX = 0
        #for kk in x_dofs:
        #    FX += f_int_total[i]

        #fx_rxn[l] = Fx
        np.save(output_path + "fx",fx_rxn)

        if t <= 5:
            u_D.u_D += .14
        else:
            u_D.u_D = u_D.u_D

        #print(cb_f_array)

        """if t <= 100: # stretch to 1300
            u_D.u_D += .003
        if t < 500 and t > 100:
            u_D.u_D =u_D.u_D
        if t < 600 and t >= 500:
            u_D.u_D += .0005
        if t < 800 and t >=600:
            u_D.u_D = u_D.u_D
        if t < 900 and t >= 800:
            u_D.u_D -= .0005
        if t >= 900:
            u_D.u_D = u_D.u_D"""
        """if t < 170 and t > 150:
            u_D.u_D -= 0.005
        else:
            u_D.u_D = u_D.u_D"""
        """if t < 5:
            u_D.u_D += 0.03
        else:
            u_D.u_D = u_D.u_D"""
        t = t + step_size

        #calarray.append(hs.Ca_conc*np.ones(no_of_int_points))
        #calcium[] = hs.Ca_conc*
        if save_output:

            active_stress_ds.iloc[0,:] = cb_f_array[:]
            active_stress_ds.to_csv(output_path + 'active_stress.csv',mode='a',header=False)

            #active_stress_ds = active_stress_ds.transpose()
            #hsl_array_ds.iloc[0,:] = hsl_array[:]
            #hsl_array_ds.to_csv(output_path + 'half_sarcomere_lengths.csv',mode='a',header=False)

            calcium_ds.iloc[0,:] = calcium[l]
            calcium_ds.to_csv(output_path + 'calcium.csv',mode='a',header=False)

            #for i in range(no_of_int_points):
            #    dumped_populations_ds.iloc[i,:] = dumped_populations[i,:]
            #dumped_populations_ds.to_csv(output_path + 'populations.csv',mode='a',header=False)

            tarray_ds[l] = tarray[l]
            tarray_ds.to_csv(output_path + 'time.csv',mode='a',header=False)

            #p_f_array_ds.iloc[0,:] = p_f_array[:]
            #p_f_array_ds.to_csv(output_path + 'myofiber_passive.csv',mode='a',header=False)

            #pgf_array_ds.iloc[0,:] = pgf_array[:]
            #pgf_array_ds.to_csv(output_path + 'gucc_fiber_pstress.csv',mode='a',header=False)

            #pgt_array_ds.iloc[0,:] = pgt_array[:]
            #pgt_array_ds.to_csv(output_path + 'gucc_trans_pstress.csv',mode='a',header=False)

            #pgs_array_ds.iloc[0,:] = pgs_array[:]
            #pgs_array_ds.to_csv(output_path + 'gucc_shear_pstress.csv',mode='a',header=False)

            #temp_overlap_ds.iloc[0,:] = temp_overlap[:]
            #temp_overlap_ds.to_csv(output_path + 'overlap.csv',mode='a',header=False)

            #alpha_array_ds.iloc[0,:] = alpha_array[:]
            #alpha_array_ds.to_csv(output_path + 'alpha.csv',mode='a',header=False)

            #delta_hsl_array_ds.iloc[0,:] = delta_hsl_array[:]
            #delta_hsl_array_ds.to_csv(output_path + 'delta_hsl.csv',mode='a',header=False)

        # Update Fiber orientation
        #f0 = f0+step_size*(Cmat*f0-f0)/sqrt(inner(Cmat*f0-f0,Cmat*f0-f0))
        #target_vec = Cmat*f0
        #print target_vec.type()
        #target_diff = target_vec - f0
        #target_diff = target_diff/sqrt(inner(target_diff,target_diff))
        #f0 = f0 + step_size*target_diff
        #File(output_path + "fiber_" +str(t)+ ".pvd") << project(f0, VectorFunctionSpace(mesh, "CG", 1))


        """for  m in range(no_of_int_points):

            for k in range(n_array_length):

                dumped_populations[l, m, k] = y_vec_array[m * n_array_length + k]"""

    rate_constants = np.zeros((no_of_x_bins,no_of_transitions + 1))

    #for l in range(no_of_x_bins):

    #    for m in range(no_of_transitions + 1):

    #        rate_constants[l,m] = Myosim.dump_rate_constants(l, m, 0)
    fluxes, rates = implement.return_rates_fenics(hs)



    #np.save("/home/fenics/shared/python_dev/test_10_pm/rates",rates)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/dumped_populations",dumped_populations)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/tarray",tarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/stress_array",strarray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/pstress_array",p_f)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/calcium",calarray)

    #np.save("/home/fenics/shared/test_10/displacements",darray)

    #np.save("/home/fenics/shared/python_dev/test_10_pm/HSL",hslarray)

    #np.save("/home/fenics/shared/test_10/DHSL",delta_hsls)
    """outputs = {
    "rates": rates,
    "dumped_populations": dumped_populations,
    "tarray": tarray,
    "strarray": strarray,
    "pstrarray": pstrarray,
    "alphaarray": darray,
    "calarray": calarray,
    "hsl": hslarray,
    #"overlap": overlaparray

    }"""
    outputs = {}

    """np.save(output_path +"dumped_populations", dumped_populations)
    np.save(output_path + "tarray", tarray)
    np.save(output_path + "stress_array", strarray)
    np.save(output_path + "hsl", hslarray)
    np.save(output_path + "overlap", overlaparray)
    np.save(output_path + "pstress_array",pstrarray)
    np.save(output_path + "j3",j3_fluxes)
    np.save(output_path + "j4",j4_fluxes)
    #np.save(output_path + "alpha_array",alphaarray)
    np.save(output_path + "calcium",calarray)"""
    fdataCa.close()

    return(outputs)
예제 #6
0
arrays_and_values["temp_overlap"] = np.zeros((no_of_int_points))
arrays_and_values["y_vec_array_new"] = np.zeros(
    ((no_of_int_points) * n_array_length))
arrays_and_values["j3_fluxes"] = np.zeros((no_of_int_points, no_of_time_steps))
arrays_and_values["j4_fluxes"] = np.zeros((no_of_int_points, no_of_time_steps))
arrays_and_values["j7_fluxes"] = np.zeros((no_of_int_points, no_of_time_steps))
arrays_and_values["y_interp"] = np.zeros((no_of_int_points) * n_array_length)
arrays_and_values["calcium"] = np.zeros(no_of_time_steps)
arrays_and_values["delta_hsl_array"] = np.zeros(no_of_int_points)

# Initialize calcium object (eventually)
# Initialize cell ion module
cell_ion_params = input_parameters["electrophys_parameters"][
    "cell_ion_parameters"]
cell_ion = cell_ion_driver.cell_ion_driver(cell_ion_params, sim_state.timestep,
                                           sim_state.sim_duration)

# Initialize calcium concentration from cell_ion module
arrays_and_values["calcium"][0] = cell_ion.calculate_concentrations(
    sim_state.timestep, 0, 0)

# Initialize windkessel
# Going to save pressure and volume of LV
Pcav_array = np.zeros(no_of_time_steps)
LVcav_array = np.zeros(no_of_time_steps)
windkessel_params = sim_state.wk_params
circ_system = CirculatorySystem.CirculatorySystem(windkessel_params)

# solution function
w = functions["w"]