Ejemplo n.º 1
0
    def initialize(self, coupling_subdomain, mesh, read_field, write_field, u_n, t=0, n=0):
        """Initializes remaining attributes. Called once, from the solver.

        :param read_field: function applied on the read field
        :param write_field: function applied on the write field
        """
        self.set_coupling_mesh(mesh, coupling_subdomain)
        self.set_read_field(read_field)
        self.set_write_field(write_field)
        self._precice_tau = self._interface.initialize()

        if self._interface.is_action_required(precice.action_write_initial_data()):
            self._interface.write_block_scalar_data(self._write_data_id, self._n_vertices, self._vertex_ids, self._write_data)
            self._interface.fulfilled_action(precice.action_write_initial_data())

        self._interface.initialize_data()

        if self._interface.is_read_data_available():
            self._interface.read_block_scalar_data(self._read_data_id, self._n_vertices, self._vertex_ids, self._read_data)

        if self._interface.is_action_required(precice.action_write_iteration_checkpoint()):
            self._u_cp = u_n.copy(deepcopy=True)
            self._t_cp = t
            self._n_cp = n
            self._interface.fulfilled_action(precice.action_write_iteration_checkpoint())

        return self._precice_tau
Ejemplo n.º 2
0
    def initialize_data(self):
        if self.interface.is_action_required(
                precice.action_write_initial_data()):
            self.interface.write_block_vector_data(self.displacement_id,
                                                   self.vertex_ids,
                                                   self.displacement)
            self.interface.mark_action_fulfilled(
                precice.action_write_initial_data())

        self.interface.initialize_data()
Ejemplo n.º 3
0
    def initialize(self, INIT_T):

        self.preciceDt = self.precice.initialize()
        if self.precice.is_action_required(
                precice.action_write_initial_data()):
            self.writeCouplingData(INIT_T)
            self.precice.fulfilled_action(precice.action_write_initial_data())

        self.precice.initialize_data()
        return self.preciceDt
    def __init__(self, mbdHelper, configFileName="../precice-config.xml"):
        self.mbd = mbdHelper
        self.interface = precice.Interface("Structure_Solver", configFileName,
                                           0, 1)  # proc no, nprocs
        self.dim = self.interface.get_dimensions()
        nodes = self.mbd.getNodes()

        # if self.dim == 2:
        # self.nodesid = np.where(nodes[:,2] < 1e-6)
        # nodes = nodes[self.nodesid]

        self.nnodes = len(nodes)

        nmeshID = self.interface.get_mesh_id("Structure_Nodes")
        self.nodeVertexIDs = self.nnodes * [0.0]
        #self.interface.set_mesh_vertices(nmeshID, self.nnodes, np.ravel(nodes[:,:self.dim]), self.nodeVertexIDs)
        #self.interface.set_mesh_vertices(nmeshID, np.ravel(nodes[:,:self.dim]))
        self.interface.set_mesh_vertices(nmeshID,
                                         np.array(nodes[:, :self.dim]))
        #self.displacements = np.array(self.dim*self.nnodes*[0.0])
        self.displacements = np.zeros((self.nnodes, self.dim))

        # ccs = self.mbd.getCellCenters()
        # self.ncells = len(ccs)
        # cmeshID = self.interface.get_mesh_id("Structure_CellCenters")
        # self.cellVertexIDs = self.ncells*[0.0]
        # self.interface.set_mesh_vertices(cmeshID, self.ncells, np.ravel(ccs[:,:self.dim]), self.cellVertexIDs)
        self.force = np.array(self.dim * self.nnodes * [0.0])

        self.displacementsID = self.interface.get_data_id(
            "DisplacementDelta", nmeshID)
        self.forceID = self.interface.get_data_id("Force", nmeshID)

        self.dt = self.interface.initialize()
        self.mbd.controlDict["timeStep"] = self.dt
        self.mbd.initializeMBDyn()
        #import ipdb; ipdb.set_trace()

        if (self.interface.is_action_required(
                precice.action_write_initial_data())):
            print("Writing initial data")
            self.interface.write_block_vector_data(self.displacementsID,
                                                   self.nodeVertexIDs,
                                                   self.displacements)
            self.interface.mark_action_fulfilled(
                precice.action_write_initial_data())

        self.interface.initialize_data()
        if (self.interface.is_read_data_available()):
            print("Reading initial data")
            self.force = self.interface.read_block_vector_data(
                self.forceID, self.nodeVertexIDs)
        print(4)
Ejemplo n.º 5
0
    def initialize(self, coupling_subdomain, mesh, read_field, write_field, 
                   u_n, dimension=2, t=0, n=0, dirichlet_boundary=None ):
        """Initializes remaining attributes. Called once, from the solver.

        :param coupling_subdomain: domain where coupling takes place
        :param mesh: fenics mesh
        :param read_field: function applied on the read field
        :param write_field: function applied on the write field
        :param u_n: initial data for solution
        :param dimension: problem dimension
        :param t: starting time
        :param n: time step n
        :param coupling_marker: boundary marker, can be used for coupling, multiple Neumann boundary conditions are applied
        """
        self._fenics_dimensions = dimension

        if self._fenics_dimensions != self._dimensions:
            logging.warning("fenics_dimension = {} and precice_dimension = {} do not match!".format(self._fenics_dimensions,
                                                                                            self._dimensions))
            if self._can_apply_2d_3d_coupling():
                logging.warning("2D-3D coupling will be applied. Z coordinates of all nodes will be set to zero.")
            else:
                raise Exception("fenics_dimension = {}, precice_dimension = {}. "
                                "No proper treatment for dimensional mismatch is implemented. Aborting!".format(
                    self._fenics_dimensions,
                    self._dimensions))
        if dirichlet_boundary is not None:
            self._Dirichlet_Boundary=dirichlet_boundary

        self.set_coupling_mesh(mesh, coupling_subdomain)
        self._set_read_field(read_field)
        self._set_write_field(write_field)
        self._precice_tau = self._interface.initialize()
        
        if self._interface.is_action_required(precice.action_write_initial_data()):
            self._write_block_data()
            self._interface.fulfilled_action(precice.action_write_initial_data())
                
        self._interface.initialize_data()

        if self._interface.is_read_data_available():
            self._read_block_data()

        if self._interface.is_action_required(precice.action_write_iteration_checkpoint()):
            self._u_cp = u_n.copy(deepcopy=True)
            self._t_cp = t
            self._n_cp = n
            self._interface.fulfilled_action(precice.action_write_iteration_checkpoint())
            
        return self._precice_tau
Ejemplo n.º 6
0
    def initialize(self,
                   coupling_subdomain,
                   mesh,
                   read_field,
                   write_field,
                   u_n,
                   dimension=2,
                   t=0,
                   n=0,
                   coupling_marker=0):
        """Initializes remaining attributes. Called once, from the solver.

        :param read_field: function applied on the read field
        :param write_field: function applied on the write field
        """
        print("Begin initializating the fenics adapter...")

        self._fenics_dimensions = dimension

        self.set_coupling_mesh(mesh, coupling_subdomain)
        self.set_read_field(read_field)
        self.set_write_field(write_field)
        self._precice_tau = self._interface.initialize()

        self._function_type = self.function_type(write_field)

        print('is action required')
        if self._interface.is_action_required(
                precice.action_write_initial_data()):
            self.write_block_data()

        self._interface.initialize_data()

        print('read available')
        if self._interface.is_read_data_available():
            self.read_block_data()
#            if self.function_type(read_field) is FunctionType.SCALAR:
#                self._interface.read_block_scalar_data(self._read_data_id, self._n_vertices, self._vertex_ids, self._read_data)
#            elif self.function_type(read_field) is FunctionType.VECTOR:
#                self._interface.read_block_vector_data(self._read_data_id, self._n_vertices, self._vertex_ids, self._read_data.ravel())
#            else:
#                raise Exception("Rank of function space is neither 0 nor 1")

        if self._interface.is_action_required(
                precice.action_write_iteration_checkpoint()):
            self._u_cp = u_n.copy(deepcopy=True)
            self._t_cp = t
            self._n_cp = n
            self._interface.fulfilled_action(
                precice.action_write_iteration_checkpoint())

        #create an integration domain for the coupled boundary
        self.dss = Measure('ds', domain=mesh, subdomain_data=coupling_marker)
        print("initialization successful")

        return self._precice_tau
Ejemplo n.º 7
0
    def write_block_data(self):
        """
        Writes the data to precice. Dependent on the dimensions
        of the simulation (2D-3D Coupling, 2D-2-D coupling or
        Scalar/Vector write function) write_data is first converted.
        """
        if self._function_type is FunctionType.SCALAR:  #write_field.value_rank() == 0:
            self._interface.write_block_scalar_data(self._write_data_id,
                                                    self._n_vertices,
                                                    self._vertex_ids,
                                                    self._write_data)
        elif self._function_type is FunctionType.VECTOR:

            if self._fenics_dimensions == 2 and self._dimensions == 3:
                #This corresponds to 2D-3D coupling
                #zeros have to be inserted for the y-entry

                #MY_CHANGE
                #precice_write_data = np.column_stack((self._write_data[:,0], np.zeros(self._n_vertices), self._write_data[:,1]))
                precice_write_data = np.column_stack(
                    (self._write_data[:, 0], self._write_data[:, 1],
                     np.zeros(self._n_vertices)))

                #print("Write data:")
                #print(precice_write_data.ravel())
                assert (precice_write_data.shape[0] == self._n_vertices
                        and precice_write_data.shape[1] == self._dimensions)
                self._interface.write_block_vector_data(
                    self._write_data_id, self._n_vertices, self._vertex_ids,
                    precice_write_data.ravel())

            elif self._fenics_dimensions == self._dimensions:
                self._interface.write_block_vector_data(
                    self._write_data_id, self._n_vertices, self._vertex_ids,
                    self._write_data.ravel())

        else:
            raise Exception("Rank of function space is neither 0 nor 1")
        self._interface.fulfilled_action(precice.action_write_initial_data())
Ejemplo n.º 8
0
    def initialize(self,
                   coupling_subdomain,
                   read_field,
                   write_field,
                   mapping=None,
                   T=None,
                   dt=None,
                   init_data1=None,
                   init_data2=None,
                   init_data3=None):
        """Initializes remaining attributes. Called once, from the solver.

        :param read_field: function applied on the read field
        :param write_field: function applied on the write field
        """

        read_function_space = read_field.function_space()
        try:
            write_function_space = write_field.function_space()
        except:
            write_function_space = read_function_space

        self.set_coupling_mesh(read_function_space, write_function_space,
                               coupling_subdomain, mapping)
        self.set_write_field(write_field)
        self.set_read_field()
        self._precice_tau = self._interface.initialize()
        #dt.assign(min(self._precice_tau, float(dt)))

        if self._interface.is_action_required(
                precice.action_write_initial_data()):
            if self.write_n_vertices > 0:
                if self._write_data_name == "Force" or self._write_data_name == "Displacement":
                    self._interface.write_block_vector_data(
                        self._write_data_id, self.write_n_vertices,
                        self.write_vertex_ids, self._write_data)
                elif self._write_data_name == "Pressure":
                    self._interface.write_block_scalar_data(
                        self._write_data_id, self.write_n_vertices,
                        self.write_vertex_ids, self._write_data)
            self._interface.fulfilled_action(
                precice.action_write_initial_data())

        self._interface.initialize_data()

        if self._interface.is_read_data_available():
            if self.read_n_vertices > 0:
                self._interface.read_block_vector_data(self._read_data_id,
                                                       self.read_n_vertices,
                                                       self.read_vertex_ids,
                                                       self._read_data)

        if self._interface.is_action_required(
                precice.action_write_iteration_checkpoint()):
            #if T:self.init_T=float(T)
            #if dt:self.init_dt=float(dt)
            #if init_data1:self.init_data1=init_data1.copy(True)
            #if init_data2:self.init_data2=init_data2.copy(True)
            #if init_data3:self.init_data3=init_data3.copy(True)
            self._interface.fulfilled_action(
                precice.action_write_iteration_checkpoint())

        #if self._interface.is_action_required(precice.action_write_iteration_checkpoint()):
        #    self.dt_init=float(dt)
        #    self._interface.fulfilled_action(precice.action_write_iteration_checkpoint())

        read_field.vector()[self.read_local_dofs] = self._read_data

        return self._precice_tau
Ejemplo n.º 9
0
def main(side='Dirichlet'):

    print("Running nutils")

    # domain size
    y_bottom, y_top = 0, 1
    x_left, x_right = 0, 2
    x_coupling = 1  # x coordinate of coupling interface

    n = 10  # number of mesh vertices per dimension

    if side == 'Dirichlet':
        x_grid = np.linspace(x_left, x_coupling, n)
    elif side == 'Neumann':
        x_grid = np.linspace(x_coupling, x_right, n)
    else:
        raise Exception('invalid side {!r}'.format(side))

    y_grid = np.linspace(y_bottom, y_top, n)

    # define the Nutils mesh
    domain, geom = nutils.mesh.rectilinear([x_grid, y_grid])

    # Nutils namespace
    ns = nutils.function.Namespace()
    ns.x = geom

    degree = 1  # linear finite elements
    ns.basis = domain.basis('std', degree=degree)
    ns.alpha = 3  # parameter of problem
    ns.beta = 1.3  # parameter of problem
    ns.u = 'basis_n ?lhs_n'  # solution
    ns.dudt = 'basis_n (?lhs_n - ?lhs0_n) / ?dt'  # time derivative
    ns.flux = 'basis_n ?fluxdofs_n'  # heat flux
    ns.f = 'beta - 2 - 2 alpha'  # rhs
    ns.uexact = '1 + x_0 x_0 + alpha x_1 x_1 + beta ?t'  # analytical solution

    # define the weak form
    res0 = domain.integral(
        '(basis_n dudt - basis_n f + basis_n,i u_,i) d:x' @ ns,
        degree=degree * 2)

    # set boundary conditions at non-coupling boundaries
    # top and bottom boundary are non-coupling for both sides
    sqr0 = domain.boundary['top'].integral(
        '(u - 1 - x_0 x_0 - alpha - beta ?t)^2 d:x' @ ns, degree=degree * 2)
    sqr0 += domain.boundary['bottom'].integral(
        '(u - 1 - x_0 x_0 - beta ?t)^2 d:x' @ ns, degree=degree * 2)
    if side == 'Dirichlet':  # left boundary is non-coupling
        sqr0 += domain.boundary['left'].integral(
            '(u - 1 - alpha x_1 x_1 - beta ?t)^2 d:x' @ ns, degree=degree * 2)
    elif side == 'Neumann':  # right boundary is non-coupling
        sqr0 += domain.boundary['right'].integral(
            '(u - 1 - x_0 x_0 - alpha x_1 x_1 - beta ?t)^2 d:x' @ ns,
            degree=degree * 2)

    # preCICE setup
    interface = precice.Interface(side, "../precice-config.xml", 0, 1)

    # define coupling mesh
    mesh_name = side + "-Mesh"
    mesh_id = interface.get_mesh_id(mesh_name)
    coupling_boundary = domain.boundary['right' if side ==
                                        'Dirichlet' else 'left']
    coupling_sample = coupling_boundary.sample('gauss', degree=degree * 2)
    vertices = coupling_sample.eval(ns.x)
    vertex_ids = interface.set_mesh_vertices(mesh_id, vertices)

    # coupling data
    write_data = "Temperature" if side == "Neumann" else "Heat-Flux"
    read_data = "Heat-Flux" if side == "Neumann" else "Temperature"
    write_data_id = interface.get_data_id(write_data, mesh_id)
    read_data_id = interface.get_data_id(read_data, mesh_id)

    # helper functions to project heat flux to coupling boundary
    projection_matrix = coupling_boundary.integrate(
        ns.eval_nm('basis_n basis_m d:x'), degree=degree * 2)
    projection_cons = np.zeros(res0.shape)
    projection_cons[projection_matrix.rowsupp(1e-15)] = np.nan

    def fluxdofs(v):
        return projection_matrix.solve(v, constrain=projection_cons)

    # helper data structure to apply heat flux correctly
    dx_function = 'd:x' @ ns

    precice_dt = interface.initialize()

    # write initial data
    if interface.is_action_required(precice.action_write_initial_data()):
        write_data = np.zeros(len(vertex_ids))
        interface.write_block_scalar_data(write_data_id, vertex_ids,
                                          write_data)
        interface.mark_action_fulfilled(precice.action_write_initial_data())

    interface.initialize_data()

    t = 0

    # initial condition
    sqr = domain.integral('(u - uexact)^2' @ ns, degree=degree * 2)
    lhs0 = nutils.solver.optimize('lhs',
                                  sqr,
                                  droptol=1e-15,
                                  arguments=dict(t=t))
    bezier = domain.sample('bezier', degree * 2)
    x, u, uexact = bezier.eval(['x_i', 'u', 'uexact'] @ ns, lhs=lhs0, t=t)
    with treelog.add(treelog.DataLog()):
        nutils.export.vtk(side + '-0',
                          bezier.tri,
                          x,
                          Temperature=u,
                          reference=uexact)

    t += precice_dt
    timestep = 0
    dt = 0.1

    while interface.is_coupling_ongoing():

        # update (time-dependent) boundary condition
        cons0 = nutils.solver.optimize('lhs',
                                       sqr0,
                                       droptol=1e-15,
                                       arguments=dict(t=t))

        # read data from interface
        if interface.is_read_data_available():
            read_data = interface.read_block_scalar_data(
                read_data_id, vertex_ids)
            read_function = coupling_sample.asfunction(read_data)

            if side == 'Dirichlet':
                sqr = coupling_sample.integral((ns.u - read_function)**2)
                cons = nutils.solver.optimize('lhs',
                                              sqr,
                                              droptol=1e-15,
                                              constrain=cons0,
                                              arguments=dict(t=t))
                res = res0
            else:
                cons = cons0
                res = res0 + coupling_sample.integral(
                    ns.basis * read_function * dx_function)

        # save checkpoint
        if interface.is_action_required(
                precice.action_write_iteration_checkpoint()):
            lhs_checkpoint = lhs0
            t_checkpoint = t
            timestep_checkpoint = timestep
            interface.mark_action_fulfilled(
                precice.action_write_iteration_checkpoint())

        # potentially adjust non-matching timestep sizes
        dt = min(dt, precice_dt)

        # solve nutils timestep
        lhs = nutils.solver.solve_linear('lhs',
                                         res,
                                         constrain=cons,
                                         arguments=dict(lhs0=lhs0, dt=dt, t=t))

        # write data to interface
        if interface.is_write_data_required(dt):
            if side == 'Dirichlet':
                flux_function = res.eval(lhs0=lhs0, lhs=lhs, dt=dt, t=t)
                write_data = coupling_sample.eval(
                    'flux' @ ns, fluxdofs=fluxdofs(flux_function))
            else:
                write_data = coupling_sample.eval('u' @ ns, lhs=lhs)

            interface.write_block_scalar_data(write_data_id, vertex_ids,
                                              write_data)

        # do the coupling
        precice_dt = interface.advance(dt)

        # advance variables
        t += dt
        timestep += 1
        lhs0 = lhs

        # read checkpoint if required
        if interface.is_action_required(
                precice.action_read_iteration_checkpoint()):
            lhs0 = lhs_checkpoint
            t = t_checkpoint
            timestep = timestep_checkpoint
            interface.mark_action_fulfilled(
                precice.action_read_iteration_checkpoint())
        else:  # go to next timestep
            bezier = domain.sample('bezier', degree * 2)
            x, u, uexact = bezier.eval(['x_i', 'u', 'uexact'] @ ns,
                                       lhs=lhs,
                                       t=t)

            with treelog.add(treelog.DataLog()):
                nutils.export.vtk(side + "-" + str(timestep),
                                  bezier.tri,
                                  x,
                                  Temperature=u,
                                  reference=uexact)

    interface.finalize()
Ejemplo n.º 10
0
vertexIDs = np.zeros(N + 1)
grid = np.zeros([N + 1, dimensions])

grid[:, 0] = np.linspace(0, L, N + 1)  # x component
grid[:, 1] = 0  # np.linspace(0, config.L, N+1)  # y component, leave blank

vertexIDs = interface.set_mesh_vertices(meshID, grid)

t = 0

print("Solid: init precice...")

# preCICE defines timestep size of solver via precice-config.xml
precice_dt = interface.initialize()

if interface.is_action_required(action_write_initial_data()):
    interface.write_block_scalar_data(crossSectionLengthID, vertexIDs,
                                      crossSectionLength)
    interface.mark_action_fulfilled(action_write_initial_data())

interface.initialize_data()

if interface.is_read_data_available():
    pressure = interface.read_block_scalar_data(pressureID, vertexIDs)

crossSection0 = crossSection0(pressure.shape[0] - 1)
pressure0 = p0 * np.ones_like(pressure)

while interface.is_coupling_ongoing():
    # When an implicit coupling scheme is used, checkpointing is required
    if interface.is_action_required(action_write_iteration_checkpoint()):
Ejemplo n.º 11
0
 def test_action_write_initial_data(self):
     return_constant = precice.action_write_initial_data()
     dummy_constant = b"dummy_write_initial_data"  # compare to test/SolverInterface.cpp
     self.assertEqual(return_constant, dummy_constant)