def test_width(self, simple_mesh: Mesh): num_val_0 = H_s(0) param_res_0 = H_s(Parameter(0)) param_val_0 = _val_from_coeff(param_res_0, simple_mesh)[0] num_val_1 = H_s(0.1) param_res_1 = H_s(Parameter(0.1)) param_val_1 = _val_from_coeff(param_res_1, simple_mesh)[0] assert isclose(num_val_0, 0, atol=0.0001) assert isclose(param_val_0, 0, atol=0.0001) assert isclose(num_val_1, 1, atol=0.0001) assert isclose(param_val_1, 1, atol=0.0001)
def TimeSlider_DrawDC(cf1,cf2,cf3,mesh,*args,**kwargs): """ Draw a (reference) time-dependent function that is discontinuous across an interface described by a level set function. Change reference time through widget slider. Args: cf1 (CoefficientFunction): level set function cf2 (CoefficientFunction): function to draw where lset is negative cf3 (CoefficientFunction): function to draw where lset is positive mesh (Mesh): Mesh Returns: widget element that allows to vary the reference time. """ DrawDC = MakeDiscontinuousDraw(Draw) if not isinstance(cf1,CoefficientFunction): cf1=CoefficientFunction(cf1) if not isinstance(cf2,CoefficientFunction): cf2=CoefficientFunction(cf2) if not isinstance(cf3,CoefficientFunction): cf3=CoefficientFunction(cf3) ts = Parameter(0) scene = DrawDC(fix_tref(cf1,ts),fix_tref(cf2,ts),fix_tref(cf3,ts),mesh,*args,**kwargs); def UpdateTime(time): ts.Set(time); scene.Redraw() return interact(UpdateTime,time=FloatSlider(description="tref:", continuous_update=False, min=0,max=1,step=.025))
def test_neg_inf(self, simple_mesh: Mesh): num_val = tanh(-1e30) param_res = tanh(Parameter(-1e30)) param_val = _val_from_coeff(param_res, simple_mesh)[0] assert isclose(num_val, -1) assert isclose(param_val, -1)
def test_0(self, simple_mesh: Mesh): num_val = tanh(0) param_res = tanh(Parameter(0)) param_val = _val_from_coeff(param_res, simple_mesh)[0] assert isclose(num_val, 0) assert isclose(param_val, 0)
def test_0(self, simple_mesh: Mesh): num_val = H_s(0.05) param_res = H_s(Parameter(0.05)) param_val = _val_from_coeff(param_res, simple_mesh)[0] assert isclose(num_val, 0.5) assert isclose(param_val, 0.5)
def test_pos_inf_num(self, simple_mesh: Mesh): num_val = H_s(1e30) param_res = H_s(Parameter(1e30)) param_val = _val_from_coeff(param_res, simple_mesh)[0] assert isclose(num_val, 1) assert isclose(param_val, 1)
def test_neg_inf_num(self, simple_mesh: Mesh): num_val = H_t(-1e30) param_res = H_t(Parameter(-1e30)) param_val = _val_from_coeff(param_res, simple_mesh)[0] assert isclose(num_val, 0) assert isclose(param_val, 0)
def TimeSlider_Draw(cf,mesh,*args,**kwargs): ts = Parameter(0) if not isinstance(cf,CoefficientFunction): cf = CoefficientFunction(cf) scene = Draw(fix_tref(cf,ts),mesh,*args,**kwargs); def UpdateTime(time): ts.Set(time); scene.Redraw() return interact(UpdateTime,time=FloatSlider(description="tref:", continuous_update=False, min=0,max=1,step=.025))
def test_shift(self, simple_mesh: Mesh): t = Parameter(0) result_0 = H_s(t - 1) result_1 = H_s(t + 1) result_0 = _val_from_coeff(result_0, simple_mesh) result_1 = _val_from_coeff(result_1, simple_mesh) assert isclose(result_0, 0) assert isclose(result_1, 1)
def test_time_varying(self, simple_mesh: Mesh): t = Parameter(-1) h = H_s(t) result_0 = _val_from_coeff(h, simple_mesh) t.Set(t.Get() + 1.05) result_05 = _val_from_coeff(h, simple_mesh) t.Set(t.Get() + 0.95) result_1 = _val_from_coeff(h, simple_mesh) assert isclose(result_0, 0) assert isclose(result_05, 0.5) assert isclose(result_1, 1)
def sol_to_vtu(output_dir_path: str, config_file_path: str, model: Union[Model, None] = None, delete_sol_file: bool = False) -> None: """ Function to take the output .sol files and convert them into .vtu for visualization. Args: output_dir_path: The path to the folder in which the .sol files are, and where the .vtu files will be saved. config_file_path: The path to the config file used by the model. model: The model that generated the .sol files. delete_sol_file: Bool to indicate whether or not to delete the original .sol files after converting to .vtu, Default is False. """ # Create config parser config = ConfigParser(config_file_path) # Being run outside of run.py, so have to create model if model is None: # Load model model_name = config.get_item(['OTHER', 'model'], str) model_class = get_model_class(model_name) model = model_class(config, Parameter(0.0)) # Number of subdivisions per element subdivision = config.get_item(['VISUALIZATION', 'subdivision'], int) # NOTE: -1 is the value used whenever an int default is needed. if subdivision == -1: subdivision = model.interp_ord # Generate a list of all .sol files sol_path_generator = Path(output_dir_path + 'sol/').rglob('*.sol') sol_path_list = [str(sol_path) for sol_path in sol_path_generator] # Number of files to convert n_files = len(sol_path_list) # Number of cores to use # NOTE: No point of starting more threads than files, and also lets us depend on modulo math later. n_threads = min(n_files, cpu_count()) # Create gridfunctions, one per thread gfus = [model.construct_gfu() for _ in range(n_threads)] # Create a list to contain the .pvd entries output_list = ['' for _ in range(n_files)] # NOTE: We HAVE to use Pool, and not ThreadPool. ThreadPool causes seg faults on the VTKOutput call. with Pool(processes=n_threads) as pool: # Create the pool and start it. It will automatically take and run the next entry when it needs it a = [ pool.apply_async( _sol_to_vtu, (gfus[i % n_threads], sol_path_list[i], output_dir_path, model.save_names, delete_sol_file, subdivision, model.mesh)) for i in range(n_files) ] # Iterate through each thread and get it's result when it's done for i in range(len(a)): # Grab the result string and insert it in the correct place in the output list output_list[i] = a[i].get() # Add the header and footer output_list.insert( 0, '<?xml version=\"1.0\"?>\n<VTKFile type=\"Collection\" version=\"0.1\"\n' + 'byte_order=\"LittleEndian\"\ncompressor=\"vtkZLibDataCompressor\">\n<Collection>\n' ) output_list.append('</Collection>\n</VTKFile>') # Write each line to the file with open(output_dir_path + 'transient.pvd', 'a+') as file: for line in output_list: file.write(line)