#=============================================================================
# Monolithic FE^2
# Nils Lange, Geralf Huetter, Bjoern Kiefer
#   Nils.Lange@imfd.tu-freiberg.de, Geralf.Huetter@imfd.tu-freiberg.de, 
#   Bjoern.Kiefer@imfd.tu-freiberg.de
# distributed under CC BY-NC-SA 4.0 license
# (https://creativecommons.org/licenses/by-nc-sa/4.0/)
# Reference: 
#   N. Lange, G. Huetter, B. Kiefer: "An efficient monolithic solution scheme for FE2 problems",
#   https://arxiv.org/abs/2101.01802
#
# Further information on the implementation, structure of the source code,
# examples and tutorials can be found in the file doc/documentation.pdf
#
#=============================================================================

import os

def set_FE2_Analysisparameters(scheme,convergence_ratio,max_iters,save_soe,
                               indefinite_matrix,symmetric_matrix,solving_process,
                               training_data='NO',simulation_time=1.0,dtime_data_dump=0.1):
	
	direct_path=os.path.abspath(".")
	fobj_out = open(direct_path+"/"+"FE2_Analysisparameters.cfg","w")
	
	#output Version number
	fobj_out.write('**MonolithFE2 Version 1.03\n')
	
	#general warning
	fobj_out.write('**Do not modify this file, otherwise it may not work properly!\n')
	#staggered/monolithic algorithm
	fobj_out.write('*Algorithm\n')
	if scheme=='staggered':
		fobj_out.write('staggered\n')
	else:
		fobj_out.write('monolithic\n')
	#save factorization in monolithic scheme?
	if not(scheme=='staggered'):
		fobj_out.write('*Factorization\n')
		if save_soe=='FALSE':
			fobj_out.write('notsaved')
		else:
			fobj_out.write('saved')
		fobj_out.write('\n')
	#max. number of equilibrium iterations in staggered scheme
	else:
		fobj_out.write('*Equilibrium_iterations\n')
		if max_iters>0 and max_iters<21:
			fobj_out.write(str(max_iters))
			fobj_out.write('\n')
		else:
			raise Exception('max. number of iterations in staggered scheme is supposed to be between 1 and 20!')
		fobj_out.write('*Convergence_ratio\n')
		s = '%1.10f' % convergence_ratio
		if convergence_ratio>0.0 and convergence_ratio<1.0:
			fobj_out.write(s)
			fobj_out.write('\n')
		else:
			raise Exception('convergence_ratio is supposed to be between 0.0 and 1.0!')
	#indefinite matrix?
	fobj_out.write('*Systemmatrix_definiteness\n')
	if indefinite_matrix=='indefinite':
		fobj_out.write('indefinite')
	else:
		fobj_out.write('positiv')
	fobj_out.write('\n')
	
	#symmetric matrix?
	fobj_out.write('*Systemmatrix_symmetry\n')
	if symmetric_matrix=='symm':
		fobj_out.write('symm')
	else:
		fobj_out.write('unsymm')
	fobj_out.write('\n')
	
	#solving process restricted by ROM modes or full?
	fobj_out.write('*Solving_Process\n')
	if solving_process=='full':
		fobj_out.write('full')
	elif solving_process=='reduced':
		fobj_out.write('reduced')
	else:
		fobj_out.write('hyperreduced')
	fobj_out.write('\n')
		
	#generate training data or not
	fobj_out.write('*Training_data\n')
	if training_data=='ROM':
		fobj_out.write('ROM\n')
		#dump the data at equally distributed time slots
		n_data_dumps=int(simulation_time/dtime_data_dump)
		fobj_out.write('*Data_dump, N='+str(n_data_dumps+1)+'\n')
		for n in range(n_data_dumps+1):
			fobj_out.write(str(dtime_data_dump*float(n)))
			if n!=n_data_dumps:
				fobj_out.write(',')
			else:
				fobj_out.write('\n')
	else:
		fobj_out.write('NO')

	fobj_out.close()
