rmsGrad = tf.sqrt(gradSq) if (numSteps % printIncrement == 0): print("Energy after " + str(numSteps) + " iterations: " +\ str(energy.numpy())) print("RSS gradient after " + str(numSteps) + " iterations: " +\ str(rmsGrad.numpy())) # Perform the gradient descent step opt.apply_gradients(zip(grads, vars)) numSteps += 1 # Postprocess the fields to avoid drift away from SU(2)/its Lie algebra scalarFieldVar.assign(0.5 * (scalarFieldVar + tf.math.conj(scalarFieldVar))) gaugeFieldVar.assign(FieldTools.projectToSu2(gaugeFieldVar)) print("Gradient descent finished in " + str(numSteps) + " iterations") print("Final energy: " + str(energy.numpy())) # Save fields as .npy files for plotting and further analysis outputPath = args.outputPath if outputPath != "": np.save(outputPath + "/X", X.numpy()) np.save(outputPath + "/Y", Y.numpy()) np.save(outputPath + "/Z", Z.numpy()) np.save(outputPath + "/scalarField", scalarFieldVar.numpy()) np.save(outputPath + "/gaugeField", gaugeFieldVar.numpy()) np.save(outputPath + "/params", params)
rssGrad = tf.sqrt(gradSq) if (numSteps % printIncrement == 0): print("Energy after " + str(numSteps) + " iterations: " +\ str(energy.numpy())) print("RSS gradient after " + str(numSteps) + " iterations: " +\ str(rssGrad.numpy())) # Perform the gradient descent step opt.apply_gradients(zip(grads, vars)) numSteps += 1 # Postprocess the fields to avoid drift away from SU(2)/its Lie algebra scalarField.assign(0.5*(scalarField + tf.math.conj(scalarField))) gaugeField.assign(FieldTools.projectToSu2(gaugeField)) while rssGrad > tol and numSteps < maxNumSteps: # Compute the field energy, with tf watching the variables with tf.GradientTape() as tape: energy = lossFn() vars = [scalarField, gaugeField] # Compute the gradients using automatic differentiation grads = tape.gradient(energy, vars) # Postprocess the gauge field gradients so they point in the tangent space # to SU(2) grads[1] = FieldTools.projectSu2Gradients(grads[1], gaugeField)