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
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()
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)
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
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
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())
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
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()
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()):
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)