def createIntegrator(self, tacs, options): """ Create the Integrator (solver) and configure it """ end_time = options['steps'] * options['step_size'] # Create an integrator for TACS if options['integrator'] == 'BDF': integrator = TACS.BDFIntegrator(tacs, options['start_time'], end_time, options['steps'], options['integration_order']) # Set other parameters for integration integrator.setRelTol(options['solver_rel_tol']) integrator.setAbsTol(options['solver_abs_tol']) integrator.setMaxNewtonIters(options['max_newton_iters']) integrator.setUseFEMat(options['femat'], options['ordering']) #integrator.setPrintLevel(options['print_level']) integrator.setOutputFrequency(options['output_freq']) return integrator
assembler = TACS.Assembler.create(comm, 1, 1, 1) conn = np.array([0], dtype=np.intc) ptr = np.array([0, 1], dtype=np.intc) assembler.setElementConnectivity(conn, ptr) assembler.setElements([spr]) assembler.initialize() # Create instance of integrator t0 = 0.0 dt = 0.01 num_steps = 1000 tf = num_steps * dt order = 2 bdf = TACS.BDFIntegrator(assembler, t0, tf, num_steps, order) # Integrate governing equations #bdf.integrate() bdf.iterate(0) for step in range(1, num_steps + 1): bdf.iterate(step) _, uvec, _, _ = bdf.getStates(num_steps) u = uvec.getArray() print "f = ", u print "df/dx, approx = ", u.imag / 1e-30 # Write out solution bdf.writeRawSolution('spring.dat', 0)
conn = np.array([0], dtype=np.intc) ptr = np.array([0, 1], dtype=np.intc) assembler.setElementConnectivity(conn, ptr) assembler.setElements([spr]) assembler.initialize() # Time marching setup tinit = 0.0 tfinal = 1000.0 # Create integrators for implicit time marching of system sizes = [1250, 2500, 5000, 10000] for nsteps in sizes: # BDF solution bdf_orders = [1, 2, 3] for order in bdf_orders: bdf = TACS.BDFIntegrator(assembler, tinit, tfinal, nsteps, order) bdf.setPrintLevel(0) bdf.integrate() bdf.writeRawSolution( 'smd-bdf' + str(order) + '-' + str(nsteps) + '.dat', 0) # DIRK solution dirk_orders = [2, 3, 4] for order in dirk_orders: dirk = TACS.DIRKIntegrator(assembler, tinit, tfinal, nsteps, order - 1) dirk.setPrintLevel(0) dirk.integrate() dirk.writeRawSolution( 'smd-dirk' + str(order) + '-' + str(nsteps) + '.dat', 0)
data = [] def print_details(method, function, index, stepsize, fvals, adj_dfdx, fd_dfdx): #data.append([method, function, stepsize, adj_dfdx, fd_dfdx]) record = dict(method=method, function=function, index=index, dh=stepsize, adjoint=adj_dfdx, complex_step=fd_dfdx, error=fd_dfdx - adj_dfdx) data.append(record) print("%10s %20s %4d %25.16e %25.16e %25.16e %25.16e %25.16e" % (method, function, index, stepsize, fvals, adj_dfdx, fd_dfdx, fd_dfdx - adj_dfdx)) #---------------------------------------------------------------------# # BDF Integrator #---------------------------------------------------------------------# for bdf_order in [1,2,3]: bdf = TACS.BDFIntegrator(tacs, tinit, tfinal, num_steps_per_sec, bdf_order) bdf.setPrintLevel(0) bdf.setJacAssemblyFreq(1) bdf.setFunction(funcs) bdf.getFuncGrad(num_design_vars, x, fvals, dfdx) bdf.getFDFuncGrad(num_design_vars, x, fvals_fd, dfdx_fd, dh) fnum = 0 for func in funcs: print_details("BDF" + str(bdf_order), func.__class__.__name__, fnum, dh, fvals[fnum], np.real(dfdx[fnum]), np.real(dfdx_fd[fnum])) fnum += 1
v[0] = 1.0 return def addResidual(self, time, res, X, v, dv, ddv): res[0] += self.m * ddv[0] + self.c * dv[0] + self.k * v[0] return def addJacobian(self, time, J, alpha, beta, gamma, X, v, dv, ddv): J[0] += alpha * self.k + beta * self.c + gamma * self.m return spr = SpringMassDamper(1, 1, 1.0, 0.5, 5.0) comm = MPI.COMM_WORLD assembler = TACS.Assembler.create(comm, 1, 1, 1) conn = np.array([0], dtype=np.intc) ptr = np.array([0, 1], dtype=np.intc) assembler.setElementConnectivity(conn, ptr) assembler.setElements([spr]) assembler.initialize() bdf = TACS.BDFIntegrator(assembler, 0.0, 100.0, 1000, 2) bdf.integrate() bdf.writeRawSolution('spring.dat', 0)
element = elements.MITC(stiff, gravity, v0, w0) mesh.setElement(i, element) tacs = mesh.createTACS(8) ###################################################################### # Time integration # ###################################################################### # Configure F5 output if tecplot output is required f5_format = "output/plate_%04d.f5" flag = (TACS.ToFH5.NODES | TACS.ToFH5.DISPLACEMENTS | TACS.ToFH5.STRAINS | TACS.ToFH5.STRESSES | TACS.ToFH5.EXTRAS) f5 = TACS.ToFH5(tacs, TACS.PY_SHELL, flag) # Create the BDF integrator solver tfinal = 0.5 num_steps_per_second = 250.0 order = 2 # Set the file output format solver = TACS.BDFIntegrator(tacs, 0.0, tfinal, num_steps_per_second, order) solver.setRelTol(1e-8) #solver.setPrintLevel(2) #solver.setOrderingType(TACS.PY_NATURAL_ORDER) #solver.setUseLapack(1) solver.setMaxNewtonIters(20) solver.configureF5Output(f5, 1, f5_format) solver.integrate()
def createSolver(params, pc): ''' Creating solver ''' if pc is not None: pc.initialize() print("number of basis terms = ", pc.getNumBasisTerms()) if params is not None: m1 = params[0] m2 = params[1] m3 = params[2] else: m1 = 1.0 m2 = 10.0 m3 = 100.0 # Create TACS M = np.matrix([[m1, 0.0, 0.0], [0.0, m2, 0.0], [0.0, 0.0, m3]]) k1 = 1.0 k2 = 10.0 k3 = 100.0 k4 = 1000.0 K = np.matrix([[k1 + k2, -k2, 0.0], [-k2, k2 + k3, -k3], [0.0, -k3, k3 + k4]]) # Spring element num_disps = 3 num_nodes = 1 dspr = SpringMassDamper(num_disps, num_nodes, M, K) if pc is not None: sprcb = SMDUpdate(dspr) sspr = STACS.PyStochasticElement(dspr, pc, sprcb) # dforce = ForcingElement(num_disps, num_nodes, amplitude=1.0, omega=10.0) # forcecb = ForceUpdate(dforce) # sforce = STACS.PyStochasticElement(dforce, pc, forcecb) if pc is not None: ndof_per_node = num_disps * pc.getNumBasisTerms() else: ndof_per_node = num_disps num_owned_nodes = 1 num_elems = 1 # Add user-defined element to TACS comm = MPI.COMM_WORLD assembler = TACS.Assembler.create(comm, ndof_per_node, num_owned_nodes, num_elems) ptr = np.array([0, 1], dtype=np.intc) conn = np.array([0], dtype=np.intc) assembler.setElementConnectivity(ptr, conn) # Set elements if pc is not None: assembler.setElements([sspr]) else: assembler.setElements([dspr]) # set Auxiliary elements # aux = TACS.AuxElements() # aux.addElement(0, sforce) # assembler.setAuxElements(aux) assembler.initialize() # Create Integrator t0 = 0.0 tf = 2.0 num_steps = 100 order = 2 integrator = TACS.BDFIntegrator(assembler, t0, tf, num_steps, order) integrator.setPrintLevel(1) integrator.integrate() return integrator
def integrate(assembler, forest, tfinal=30.0, nsteps=30, output=False): # Create the BDF integrator tinit = 0.0 order = 2 bdf = TACS.BDFIntegrator(assembler, tinit, tfinal, nsteps, order) bdf.setPrintLevel(0) bdf.setAbsTol(1e-6) bdf.setRelTol(1e-15) if output: # Set the output file name flag = (TACS.OUTPUT_CONNECTIVITY | TACS.OUTPUT_NODES | TACS.OUTPUT_DISPLACEMENTS | TACS.OUTPUT_EXTRAS) f5 = TACS.ToFH5(assembler, TACS.PLANE_STRESS_ELEMENT, flag) bdf.setFH5(f5) bdf.setOutputFrequency(1) bdf.setOutputPrefix('time_history/') # Define the functions of interest temp0 = functions.KSTemperature(assembler, 50.0) temp0.setKSTemperatureType('discrete') elems, _ = get_elems_and_surfs(['battery_0']) temp0.setDomain(elems) temp1 = functions.KSTemperature(assembler, 50.0) temp1.setKSTemperatureType('discrete') elems, _ = get_elems_and_surfs(['battery_1']) temp1.setDomain(elems) temp2 = functions.KSTemperature(assembler, 50.0) temp2.setKSTemperatureType('discrete') elems, _ = get_elems_and_surfs(['battery_2']) temp2.setDomain(elems) # Set the functions into the integrator class bdf.setFunctions([temp0, temp1, temp2]) # Create a vector that will store the instantaneous traction # load at any point in time forces = assembler.createVec() # Compute the tractions due to a unit input heat flux unit_forces = update_force(forest, assembler, qdot_in=1.0) # Iterate in time to march the equations of motion forward # in time t_array = np.linspace(tinit, tfinal, nsteps + 1) for i, t in enumerate(t_array): # Compute the magnitude of the input heat flux q_in = qdot_in_func(t) # Copy the unit force values and scale by the heat flux forces.copyValues(unit_forces) forces.scale(q_in) # Iterate forward in time for one time step bdf.iterate(i, forces=forces) # Compute the nodal sensitivities fvals = bdf.evalFunctions([temp0, temp1, temp2]) bdf.integrateAdjoint() df0dXpt = bdf.getXptGradient(0) df1dXpt = bdf.getXptGradient(1) df2dXpt = bdf.getXptGradient(2) dfdXpt = [df0dXpt, df1dXpt, df2dXpt] # Extract the time history qvals = np.zeros(nsteps + 1) tvals = np.zeros(nsteps + 1) for time_step in range(nsteps + 1): # Extract vectors time, q, _, _ = bdf.getStates(time_step) # Extract Arrays qarray = q.getArray() qvals[time_step] = np.amax(qarray) tvals[time_step] = time # Evaluate the functions at every time step temp0_vals = np.zeros(nsteps + 1) temp1_vals = np.zeros(nsteps + 1) temp2_vals = np.zeros(nsteps + 1) for time_step in range(nsteps + 1): # Extract vectors _, q, qdot, qddot = bdf.getStates(time_step) # Compute the function values assembler.setVariables(q) fvals = assembler.evalFunctions([temp0, temp1, temp2]) temp0_vals[time_step] = fvals[0] temp1_vals[time_step] = fvals[1] temp2_vals[time_step] = fvals[2] fvals = [temp0_vals, temp1_vals, temp2_vals] return tvals, qvals, fvals, dfdXpt