def test_spbox_field(self): """ 'Field' vs. 'coors'. """ mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.mesh') coors = mesh.coors.copy() bbox = nm.vstack((nm.amin(coors, 0), nm.amax(coors, 0))).T coors_1 = coors.copy() alpha = coors[:, 0] spbox = SplineBox(bbox, coors, nsg=[1, 2], field=alpha) dv1 = spbox.evaluate_derivative(6, 1) spbox.move_control_point(6, -0.2) c1 = spbox.evaluate() coors_1[:, 0] = c1[:, 0] alpha = coors[:, 1] spbox = SplineBox(bbox, coors, nsg=[1, 2], field=alpha) dv2 = spbox.evaluate_derivative(6, 1) spbox.move_control_point(6, 0.2) c2 = spbox.evaluate() coors_1[:, 1] = c2[:, 0] spbox = SplineBox(bbox, coors, nsg=[1, 2]) dv = spbox.evaluate_derivative(6, [1, 1]) spbox.move_control_point(6, [-0.2, 0.2]) coors_2 = spbox.evaluate() rel_coor_dist = nm.linalg.norm(coors_2 - coors_1)\ / nm.linalg.norm(coors_2) ok = rel_coor_dist < tolerance rel_dvel_dist = nm.linalg.norm(dv - nm.hstack([dv1, dv2]))\ / nm.linalg.norm(dv) ok = ok and rel_dvel_dist < tolerance if not ok: self.report('modified coordinates do not match, relative error:') self.report(rel_coor_dist) self.report('derivatives do not match, relative error:') self.report(rel_dvel_dist) return ok
def test_sensitivity(self): from sfepy.discrete import Variables from sfepy.mesh.splinebox import SplineBox tolerance = 1e-4 ok = True pb = self.problem variables = Variables.from_conf(self.conf.variables, pb.fields) for var_name in variables.names: var = variables[var_name] n_dof = var.field.n_nod * var.field.shape[0] aux = nm.arange(n_dof, dtype=nm.float64) var.set_data(aux) mesh = pb.domain.mesh bbox = nm.array(mesh.get_bounding_box()).T spbox = SplineBox(bbox, mesh.coors) dvel_modes = [ # expand inner cylinder, no volume change [([20, 21, 22, 23], (-1, -1, 0)), ([24, 25, 26, 27], (-1, 1, 0)), ([36, 37, 38, 39], (1, -1, 0)), ([40, 41, 42, 43], (1, 1, 0))], # volume change [(range(16, 32), (0.2, 0, 0)), (range(32, 48), (0.4, 0, 0)), (range(48, 52), (0.6, 0.2, 0.2)), (range(52, 56), (0.8, 0.2, 0.3)), (range(56, 60), (1.0, 0.2, 0.4)), (range(60, 64), (1.2, 0.2, 0.5))], ] r4 = range(4) cp_pos = {i*16 + j*4 + k: (i, j, k) for k in r4 for j in r4 for i in r4} # compute design velocities dvels = [] for dv_mode in dvel_modes: dvel = 0 for pts, dir in dv_mode: for pt in pts: dvel += spbox.evaluate_derivative(cp_pos[pt], dir) dvels.append(dvel) for tname_sa, tname, rname, mat, var1, var2 in test_terms: args = [] if mat is None else [mat] args += [var1] if var2 is None else [var1, var2] term = '%s.i.%s(%s)' % (tname, rname, ', '.join(args)) term_sa = '%s.i.%s(%s)' % (tname_sa, rname, ', '.join(args + ['V'])) val = pb.evaluate(term, var_dict=variables.as_dict()) self.report('%s: %s' % (tname, val)) dt = 1e-6 for ii, dvel in enumerate(dvels): val = pb.evaluate(term, var_dict=variables.as_dict()) variables['V'].set_data(dvel) val_sa = pb.evaluate(term_sa, var_dict=variables.as_dict()) self.report('%s - mesh_velocity mode %d' % (tname_sa, ii)) # mesh perturbation + new_coors = modify_mesh(dt/2., spbox, dvel_modes[ii], cp_pos) pb.set_mesh_coors(new_coors, update_fields=True) val1 = pb.evaluate(term, var_dict=variables.as_dict()) # mesh perturbation - new_coors = modify_mesh(-dt/2., spbox, dvel_modes[ii], cp_pos) pb.set_mesh_coors(new_coors, update_fields=True) val2 = pb.evaluate(term, var_dict=variables.as_dict()) val_fd = (val1 - val2) / dt err = nm.abs(val_sa - val_fd) / nm.linalg.norm(val_sa) self.report('term: %s' % val) self.report('sensitivity term: %s' % val_sa) self.report('finite differences: %s' % val_fd) self.report('relative error: %s' % err) _ok = err < tolerance ok = ok and _ok return ok