def __init__(self, rotation_axis_initial_point, rotation_axis_final_point, angular_velocity_module): self.a_init = Vector(rotation_axis_initial_point) self.a_final = Vector(rotation_axis_final_point) self.omega = angular_velocity_module self.axis = Vector(Rotator.Normalize(self.a_final - self.a_init)) self.CalculateRodriguesMatrices(self.axis)
def ApplyForwardCoupling(self, alpha='None'): super(CandelierDEMSolver, self).ApplyForwardCoupling(alpha) for node in self.dem_solver.spheres_model_part.Nodes: omega = candelier_pp.omega r = Vector([node.X, node.Y, node.Z]) vx = -omega * r[1] vy = omega * r[0] v = Vector([vx, vy, 0]) ax = -r[0] * omega**2 ay = -r[1] * omega**2 a = Vector([ax, ay, 0]) if self.is_rotating_frame: v = self.GetVelocityRelativeToMovingFrame(r_rel=r, v_glob=v) a = self.GetAccelerationRelativeToMovingFrame(r_rel=r, v_rel=v, a_glob=a) node.SetSolutionStepValue(Kratos.FLUID_VEL_PROJECTED, v) node.SetSolutionStepValue(Kratos.FLUID_ACCEL_PROJECTED, a) if candelier_pp.include_lift: vort = Vector([0.0, 0.0, 2.0 * omega]) node.SetSolutionStepValue(Kratos.FLUID_VORTICITY_PROJECTED, vort)
def PerformZeroStepInitializations(self): self.mat_deriv_errors = [] self.laplacian_errors = [] self.current_mat_deriv_errors = np.zeros(2) self.current_laplacian_errors = np.zeros(2) for node in self.fluid_model_part.Nodes: vel = Vector(3) coor = Vector([node.X, node.Y, node.Z]) self.flow_field.Evaluate(0.0, coor, vel, 0) node.SetSolutionStepValue(Kratos.VELOCITY, vel)
def ApplyForwardCouplingOfVelocityToAuxVelocityOnly(self, alpha=None): for node in self.dem_solver.spheres_model_part.Nodes: r = Vector([node.X, node.Y, node.Z]) new_vx = - candelier_pp.omega * r[1] new_vy = candelier_pp.omega * r[0] new_v = Vector([new_vx, new_vy, 0.]) if self.is_rotating_frame: new_v = self.GetVelocityRelativeToMovingFrame(r_rel = r, v_glob = new_v) # the current FLUID_VEL_PROJECTED is still needed and so we use # AUX_VEL to store it instead. node.SetSolutionStepValue(Kratos.AUX_VEL, new_v)
def PerformZeroStepInitializations(self): import random #from random import randint L = self.project_parameters.L #U = self.project_parameters.U #k = self.project_parameters.k #omega = self.project_parameters.omega N_positions = 100 L *= math.pi possible_xs = [ 2 * L * (i + 1) / N_positions for i in range(N_positions) ] i_position = 0 for node in self.spheres_model_part.Nodes: rand_x = 2 * L * random.random() rand_y = self.project_parameters.BoundingBoxMinY + ( self.project_parameters.BoundingBoxMaxY - self.project_parameters.BoundingBoxMinY) * random.random() init_x = node.X init_y = node.Y #rand_x = possible_xs[randint(0, N_positions - 1)] #rand_y = possible_xs[randint(0, N_positions - 1)] #rand_x = possible_xs[min(i_position // N_positions, N_positions - 1)] #rand_y = possible_xs[min(i_position // N_positions, N_positions - 1)] rand_x = possible_xs[i_position // N_positions] rand_y = possible_xs[i_position % N_positions] node.X = rand_x node.Y = rand_y node.SetSolutionStepValue(Kratos.DISPLACEMENT_X, rand_x - init_x) node.SetSolutionStepValue(Kratos.DISPLACEMENT_Y, rand_y - init_y) i_position += 1 for node in self.spheres_model_part.Nodes: vel = Vector(3) coor = Vector(3) coor[0] = node.X coor[1] = node.Y coor[2] = node.Z self.flow_field.Evaluate(0.0, coor, vel, 0) node.SetSolutionStepValue(Kratos.VELOCITY_X, vel[0]) node.SetSolutionStepValue(Kratos.VELOCITY_Y, vel[1]) node.SetSolutionStepValue(Kratos.VELOCITY_Z, vel[2]) node.SetSolutionStepValue(Kratos.VELOCITY_OLD_X, vel[0]) node.SetSolutionStepValue(Kratos.VELOCITY_OLD_Y, vel[1]) node.SetSolutionStepValue(Kratos.VELOCITY_OLD_Z, vel[2]) node.SetSolutionStepValue(Kratos.SLIP_VELOCITY_X, vel[0]) node.SetSolutionStepValue(Kratos.SLIP_VELOCITY_Y, vel[1]) node.SetSolutionStepValue(Kratos.SLIP_VELOCITY_Z, vel[2])
def AddExtraProcessInfoVariablesToFluidModelPart(self, parameters, fluid_model_part): VariablesManager.AddFrameOfReferenceRelatedVariables( parameters, fluid_model_part) fluid_model_part.ProcessInfo.SetValue(Kratos.FRACTIONAL_STEP, 1) if parameters["custom_fluid"]["body_force_on_fluid_option"].GetBool(): gravity = self.project_parameters["gravity_parameters"][ "direction"].GetVector() gravity *= self.project_parameters["gravity_parameters"][ "modulus"].GetDouble() fluid_model_part.ProcessInfo.SetValue(Kratos.GRAVITY, gravity) else: fluid_model_part.ProcessInfo.SetValue(Kratos.GRAVITY, Vector([0.0] * 3)) if parameters["laplacian_calculation_type"].GetInt( ) == 3: # recovery through solving a system fluid_model_part.ProcessInfo.SetValue( Kratos.COMPUTE_LUMPED_MASS_MATRIX, 1) elif (parameters["material_acceleration_calculation_type"].GetInt() == 4 or parameters["material_acceleration_calculation_type"].GetInt() == 5 or parameters["material_acceleration_calculation_type"].GetInt() == 6): # recovery by solving a system fluid_model_part.ProcessInfo.SetValue( Kratos.COMPUTE_LUMPED_MASS_MATRIX, 0) if parameters["material_acceleration_calculation_type"].GetInt( ) == 5 or parameters["material_acceleration_calculation_type"].GetInt( ) == 6: fluid_model_part.ProcessInfo.SetValue(Kratos.CURRENT_COMPONENT, 0)
def __init__(self, model, project_parameters, field_utility, fluid_solver, dem_solver, variables_manager): super().__init__(model, project_parameters, field_utility, fluid_solver, dem_solver, variables_manager) self.frame_angular_vel = Vector([0, 0, self.project_parameters['frame_of_reference']["angular_velocity_of_frame_Z"].GetDouble()]) self.omega = self.project_parameters['frame_of_reference']["angular_velocity_of_frame_Z"].GetDouble() candelier_pp.include_lift = PT.RecursiveFindParametersWithCondition(self.project_parameters["properties"], 'vorticity_induced_lift_parameters', condition=lambda value: not (value['name'].GetString()=='default'))
def SetToZero(self, variable): if type(variable).__name__ == 'DoubleVariable': self.custom_functions_tool.SetValueOfAllNotes( self.model_part, 0.0, variable) elif type(variable).__name__ == 'Array1DVariable3': self.custom_functions_tool.SetValueOfAllNotes( self.model_part, Vector([0, 0, 0]), variable)
def AddFrameOfReferenceRelatedVariables(parameters, model_part): frame_of_reference_type = parameters["frame_of_reference"][ "frame_type"].GetInt() model_part.ProcessInfo.SetValue(Kratos.FRAME_OF_REFERENCE_TYPE, frame_of_reference_type) if frame_of_reference_type == 1: # Rotating frame angular_velocity_of_frame = Vector(3) angular_velocity_of_frame[:] = [ parameters['frame_of_reference']["angular_velocity_of_frame" + comp].GetDouble() for comp in ['_X', '_Y', '_Z'] ][:] model_part.ProcessInfo.SetValue( Kratos.ANGULAR_VELOCITY_MOVING_FRAME, angular_velocity_of_frame) if frame_of_reference_type >= 2: # Gemeral frame angular_velocity_of_frame_old = Vector(3) angular_velocity_of_frame_old[:] = [ parameters['frame_of_reference'][ "angular_velocity_of_frame_old" + comp].GetDouble() for comp in ['_X', '_Y', '_Z'] ][:] acceleration_of_frame_origin = Vector(3) acceleration_of_frame_origin[:] = [ parameters['frame_of_reference'][ "acceleration_of_frame_origin" + comp].GetDouble() for comp in ['_X', '_Y', '_Z'] ][:] angular_acceleration_of_frame = Vector(3) angular_acceleration_of_frame[:] = [ parameters['frame_of_reference'][ "angular_acceleration_of_frame" + comp].GetDouble() for comp in ['_X', '_Y', '_Z'] ][:] model_part.ProcessInfo.SetValue( Kratos.ANGULAR_VELOCITY_MOVING_FRAME_OLD, angular_velocity_of_frame_old) model_part.ProcessInfo.SetValue( Kratos.ACCELERATION_MOVING_FRAME_ORIGIN, acceleration_of_frame_origin) model_part.ProcessInfo.SetValue( Kratos.ANGULAR_ACCELERATION_MOVING_FRAME, angular_acceleration_of_frame)
def SetBetaParameters(self): Add = self.project_parameters.AddEmptyValue if self.project_parameters["custom_dem"]["type_of_dem_inlet"].GetString() == 'ForceImposed': Add("inlet_force_vector").SetVector(Vector([0., 0., 1.])) # TODO: generalize # Setting body_force_per_unit_mass_variable_name Add("body_force_per_unit_mass_variable_name").SetString('BODY_FORCE') self.project_parameters["dem_parameters"].AddEmptyValue("do_print_results_option").SetBool(self.do_print_results)
def Rotate(self, model_part, time): Say('Starting mesh movement...') R, Rp = self.GetRotationMatrices(time) for node in model_part.Nodes: P0 = np.array([node.X0, node.Y0, node.Z0]) P = self.a_init + R.dot(P0 - self.a_init) Displacement = P - P0 Velocity = Rp.dot(P0 - self.a_init) node.X, node.Y, node.Z = P[0], P[1], P[2] node.SetSolutionStepValue(Kratos.DISPLACEMENT, Vector(list(Displacement))) node.SetSolutionStepValue(Kratos.MESH_VELOCITY, Vector(list(Velocity))) Say('Mesh movement finshed.')
def ReturnExactVelocity(self, t, x, y, z): interpolate_process_data = self.project_parameters['processes']['check_interpolated_fluid_velocity'][0] interpolate_process_parameters = interpolate_process_data['Parameters'] field_def = [entry.GetString() for entry in interpolate_process_parameters['value']] field = [eval(field_def[0]), eval(field_def[1]), eval(field_def[2])] return Vector(field)
def test_vector_interface(self): # Read and check Vectors from a Parameters-Object tmp = Parameters("""{ "valid_vectors" : [ [] ], "false_vectors" : [ [[]], [[2,3],2], [2,3,[2]], [2,3,[]], [{"key":3},2], [2,3,{"key":3}], [true,2], [2,3,true], [5,"string",2] ] }""") # Check the IsVector Method for i in range(tmp["valid_vectors"].size()): valid_vector = tmp["valid_vectors"][i] self.assertTrue(valid_vector.IsVector()) for i in range(tmp["false_vectors"].size()): false_vector = tmp["false_vectors"][i] self.assertFalse(false_vector.IsVector()) # Check the GetVector Method also on the valid Matrices for i in range(tmp["valid_vectors"].size()): valid_vector = tmp["valid_vectors"][i] valid_vector.GetVector() # Check that the errors of the GetVector method are thrown correctly for i in range(tmp["false_vectors"].size()): false_vector = tmp["false_vectors"][i] with self.assertRaises(RuntimeError): false_vector.GetVector() # Manually assign and check a Vector vec = Vector(3) vec[0] = 1.32 vec[1] = -2.22 vec[2] = 5.5 tmp.AddEmptyValue("vector_value") tmp["vector_value"].SetVector(vec) self.assertTrue(tmp["vector_value"].IsVector()) V2 = tmp["vector_value"].GetVector() self.assertEqual(V2[0],1.32) self.assertEqual(V2[1],-2.22) self.assertEqual(V2[2],5.5)
def AddExtraProcessInfoVariablesToFluidModelPart(self, parameters, fluid_model_part): VariablesManager.AddFrameOfReferenceRelatedVariables( parameters, fluid_model_part) fluid_model_part.ProcessInfo.SetValue(Kratos.FRACTIONAL_STEP, 1) if parameters["custom_fluid"]["body_force_on_fluid_option"].GetBool(): gravity = self.project_parameters["gravity_parameters"][ "direction"].GetVector() gravity *= self.project_parameters["gravity_parameters"][ "modulus"].GetDouble() fluid_model_part.ProcessInfo.SetValue(Kratos.GRAVITY, gravity) else: fluid_model_part.ProcessInfo.SetValue(Kratos.GRAVITY, Vector([0.0] * 3)) if parameters["laplacian_calculation_type"].GetInt( ) == 3: # recovery through solving a system fluid_model_part.ProcessInfo.SetValue( Kratos.COMPUTE_LUMPED_MASS_MATRIX, 1) elif (parameters["material_acceleration_calculation_type"].GetInt() == 4 or parameters["material_acceleration_calculation_type"].GetInt() == 5 or parameters["material_acceleration_calculation_type"].GetInt() == 6): # recovery by solving a system fluid_model_part.ProcessInfo.SetValue( Kratos.COMPUTE_LUMPED_MASS_MATRIX, 0) if parameters["material_acceleration_calculation_type"].GetInt( ) == 5 or parameters["material_acceleration_calculation_type"].GetInt( ) == 6: fluid_model_part.ProcessInfo.SetValue(Kratos.CURRENT_COMPONENT, 0) if parameters["non_newtonian_fluid"]["non_newtonian_option"].GetBool(): fluid_model_part.ProcessInfo.SetValue( Kratos.YIELD_STRESS, parameters["non_newtonian_fluid"]["yield_stress"].GetDouble()) fluid_model_part.ProcessInfo.SetValue( Kratos.REGULARIZATION_COEFFICIENT, parameters["non_newtonian_fluid"] ["regularization_coefficient"].GetDouble()) fluid_model_part.ProcessInfo.SetValue( Kratos.POWER_LAW_K, parameters["non_newtonian_fluid"]["power_law_k"].GetDouble()) fluid_model_part.ProcessInfo.SetValue( Kratos.POWER_LAW_N, parameters["non_newtonian_fluid"]["power_law_n"].GetDouble())
def test_add_methods(self): # This method checks all the "GetXXX" Methods if they throw an error tmp = Parameters("""{}""") key = "int" tmp.AddInt(key, 10) self.assertEqual(tmp[key].GetInt(), 10) key = "double" tmp.AddDouble(key, 2.0) self.assertEqual(tmp[key].GetDouble(), 2.0) key = "bool" tmp.AddBool(key, True) self.assertEqual(tmp[key].GetBool(), True) key = "string" tmp.AddString(key, "hello") self.assertEqual(tmp[key].GetString(), "hello") key = "vector" vector = Vector(3) vector[0] = 5.2 vector[1] = -3.1 vector[2] = 4.33 tmp.AddVector(key, vector) V = tmp[key].GetVector() self.assertEqual(V[0], 5.2) self.assertEqual(V[1], -3.1) self.assertEqual(V[2], 4.33) key = "matrix" matrix = Matrix(3, 2) matrix[0, 0] = 1.0 matrix[0, 1] = 2.0 matrix[1, 0] = 3.0 matrix[1, 1] = 4.0 matrix[2, 0] = 5.0 matrix[2, 1] = 6.0 tmp.AddMatrix(key, matrix) A = tmp[key].GetMatrix() self.assertEqual(A[0, 0], 1.0) self.assertEqual(A[0, 1], 2.0) self.assertEqual(A[1, 0], 3.0) self.assertEqual(A[1, 1], 4.0) self.assertEqual(A[2, 0], 5.0) self.assertEqual(A[2, 1], 6.0)
def test_vector_interface(self): tmp = Parameters("""{ }""") # Manually assign and check a Vector vec = Vector(3) vec[0] = 1.32 vec[1] = -2.22 vec[2] = 5.5 tmp.AddEmptyValue("vector_value") tmp["vector_value"].SetVector(vec) self.assertTrue(tmp["vector_value"].IsVector()) V2 = tmp["vector_value"].GetVector() self.assertEqual(V2[0], 1.32) self.assertEqual(V2[1], -2.22) self.assertEqual(V2[2], 5.5)
def CalculateElementNeighbourDistances( self, model_part, intersecting_surface_semi_thickness): for node in model_part.Nodes: distance = node.GetSolutionStepValue( Kratos.DISTANCE) - intersecting_surface_semi_thickness node.SetSolutionStepValue(Kratos.DISTANCE, 0, distance) if (distance < 0): node.Fix(Kratos.PRESSURE) node.Fix(Kratos.VELOCITY_X) node.Fix(Kratos.VELOCITY_Y) node.Fix(Kratos.VELOCITY_Z) for element in model_part.Elements: negative = 0 positive = 0 for node in element.GetNodes(): d = node.GetSolutionStepValue(Kratos.DISTANCE) if (d >= 0.0): positive = positive + 1 else: negative = negative + 1 if ((negative > 0) and (positive > 0)): tmp = Vector(4) i = 0 element.SetValue(Kratos.SPLIT_ELEMENT, True) for node in element.GetNodes(): d = node.GetSolutionStepValue(Kratos.DISTANCE) tmp[i] = d i = i + 1 element.SetValue(Kratos.ELEMENTAL_DISTANCES, tmp)
def __init__(self, model, project_parameters, field_utility, fluid_solver, dem_solver, variables_manager): super(CandelierDEMSolver, self).__init__(model, project_parameters, field_utility, fluid_solver, dem_solver, variables_manager) self.frame_angular_vel = Vector([0, 0, self.project_parameters['frame_of_reference']["angular_velocity_of_frame_Z"].GetDouble()]) self.omega = self.project_parameters['frame_of_reference']["angular_velocity_of_frame_Z"].GetDouble()
def CalculateRecoveryErrors(self, time): L2_norm_mat_deriv = 0. L2_norm_mat_deriv_error = 0. L2_norm_laplacian = 0. L2_norm_laplacian_error = 0. max_mat_deriv_error = 0. max_laplacian_error = 0. total_volume = 0. calc_mat_deriv = np.zeros(3) calc_laplacian = np.zeros(3) mat_deriv = Vector(3) laplacian = Vector(3) for node in self.fluid_model_part.Nodes: nodal_volume = node.GetSolutionStepValue(Kratos.NODAL_AREA) total_volume += nodal_volume coor = Vector([node.X, node.Y, node.Z]) self.flow_field.CalculateConvectiveDerivative( 0., coor, mat_deriv, 0) self.flow_field.CalculateLaplacian(0., coor, laplacian, 0) calc_mat_deriv = node.GetSolutionStepValue( Kratos.MATERIAL_ACCELERATION) calc_laplacian = node.GetSolutionStepValue( Kratos.VELOCITY_LAPLACIAN) module_mat_deriv_squared = sum(x**2 for x in mat_deriv) module_laplacian_squared = sum(x**2 for x in laplacian) L2_norm_mat_deriv += module_mat_deriv_squared * nodal_volume L2_norm_laplacian += module_laplacian_squared * nodal_volume diff_mat_deriv = calc_mat_deriv - mat_deriv diff_laplacian = calc_laplacian - laplacian node.SetSolutionStepValue(Kratos.VECTORIAL_ERROR, Vector(list(diff_mat_deriv))) node.SetSolutionStepValue(Kratos.VECTORIAL_ERROR_1, Vector(list(diff_laplacian))) module_mat_deriv_error_squared = sum(x**2 for x in diff_mat_deriv) module_laplacian_error_squared = sum(x**2 for x in diff_laplacian) L2_norm_mat_deriv_error += module_mat_deriv_error_squared * nodal_volume L2_norm_laplacian_error += module_laplacian_error_squared * nodal_volume max_mat_deriv_error = max(max_mat_deriv_error, module_mat_deriv_error_squared) max_laplacian_error = max(max_laplacian_error, module_laplacian_error_squared) L2_norm_mat_deriv **= 0.5 L2_norm_mat_deriv /= total_volume**0.5 L2_norm_mat_deriv_error **= 0.5 L2_norm_mat_deriv_error /= total_volume**0.5 L2_norm_laplacian **= 0.5 L2_norm_laplacian /= total_volume**0.5 L2_norm_laplacian_error **= 0.5 L2_norm_laplacian_error /= total_volume**0.5 max_mat_deriv_error **= 0.5 max_laplacian_error **= 0.5 if L2_norm_mat_deriv > 0 and L2_norm_laplacian > 0: SDP.MultiplyNodalVariableByFactor(self.fluid_model_part, Kratos.VECTORIAL_ERROR, 1.0 / L2_norm_mat_deriv) SDP.MultiplyNodalVariableByFactor(self.fluid_model_part, Kratos.VECTORIAL_ERROR_1, 1.0 / L2_norm_laplacian) self.current_mat_deriv_errors[ 0] = L2_norm_mat_deriv_error / L2_norm_mat_deriv self.current_mat_deriv_errors[ 1] = max_mat_deriv_error / L2_norm_mat_deriv self.current_laplacian_errors[ 0] = L2_norm_laplacian_error / L2_norm_laplacian self.current_laplacian_errors[ 1] = max_laplacian_error / L2_norm_laplacian self.mat_deriv_errors.append(self.current_mat_deriv_errors) self.laplacian_errors.append(self.current_laplacian_errors) text_width = 40 print('\n' + '-.' * text_width) print('L2 error for the material derivative'.ljust(text_width), self.current_mat_deriv_errors[0]) print('max error for the material derivative'.ljust(text_width), self.current_mat_deriv_errors[1]) print('L2 error for the laplacian'.ljust(text_width), self.current_laplacian_errors[0]) print('max error for the laplacian'.ljust(text_width), self.current_laplacian_errors[1]) print('-.' * text_width + '\n')
def Cross(a, b): c0 = a[1]*b[2] - a[2]*b[1] c1 = a[2]*b[0] - a[0]*b[2] c2 = a[0]*b[1] - a[1]*b[0] return Vector([c0, c1, c2])
def ComputeVelocityError(self): for node in self.error_model_part.Nodes: vectorial_error = Vector( node.GetSolutionStepValue(KratosMultiphysics.VELOCITY) - node.GetSolutionStepValue(SDEM.EXACT_VELOCITY)) node.SetSolutionStepValue(SDEM.VECTORIAL_ERROR, vectorial_error)
def test_set_methods(self): # This method checks all the "GetXXX" Methods if they throw an error tmp = Parameters( """{ "int_value" : 0, "double_value": 0.0, "bool_value" : false, "string_value" : "", "vector_value" : [], "matrix_value" : [[0]] }""" ) # if you add more values to this, make sure to add the corresponding in the loop for key in tmp.keys(): val_type = key[:-6] # removing "_value" # Int and Double are checked tgth bcs both internally call "IsNumber" if val_type == "int" or val_type == "double": if val_type == "int": tmp[key].SetInt(10) self.assertEqual(tmp[key].GetInt(), 10) else: with self.assertRaises(RuntimeError): tmp[key].GetInt() if val_type == "double" or val_type == "int": if val_type == "double": tmp[key].SetDouble(2.0) self.assertEqual(tmp[key].GetDouble(), 2.0) else: with self.assertRaises(RuntimeError): tmp[key].GetDouble() if val_type == "bool": tmp[key].SetBool(True) self.assertEqual(tmp[key].GetBool(), True) else: with self.assertRaises(RuntimeError): tmp[key].GetBool() if val_type == "string": tmp[key].SetString("hello") self.assertEqual(tmp[key].GetString(), "hello") else: with self.assertRaises(RuntimeError): tmp[key].GetString() if val_type == "vector": vector = Vector(3) vector[0] = 5.2 vector[1] = -3.1 vector[2] = 4.33 tmp[key].SetVector(vector) V = tmp[key].GetVector() self.assertEqual(V[0], 5.2) self.assertEqual(V[1], -3.1) self.assertEqual(V[2], 4.33) else: with self.assertRaises(RuntimeError): tmp[key].GetVector() if val_type == "matrix": matrix = Matrix(3, 2) matrix[0, 0] = 1.0 matrix[0, 1] = 2.0 matrix[1, 0] = 3.0 matrix[1, 1] = 4.0 matrix[2, 0] = 5.0 matrix[2, 1] = 6.0 tmp[key].SetMatrix(matrix) A = tmp[key].GetMatrix() self.assertEqual(A[0, 0], 1.0) self.assertEqual(A[0, 1], 2.0) self.assertEqual(A[1, 0], 3.0) self.assertEqual(A[1, 1], 4.0) self.assertEqual(A[2, 0], 5.0) self.assertEqual(A[2, 1], 6.0) else: with self.assertRaises(RuntimeError): tmp[key].GetMatrix()