78 flexibleParams_.append(
true);
83 if (IteratorT::nFlexibleParams() == 0) {
84 IteratorT::isFlexible_ =
false;
88 flexibleParams_.clear();
89 for (
int i = 0; i < np; i++) {
90 flexibleParams_.append(
false);
99 AmIterTmplT::readMixingParameters(in);
102 interaction_.setNMonomer(system().mixture().nMonomer());
108 template <
int D,
class T>
112 out <<
"Iterator times contributions:\n";
121 template <
int D,
class T>
125 interaction_.update(system().interaction());
133 template <
int D,
class T>
134 int AmIteratorGrid<D,T>::nElements()
136 const int nMonomer = system().mixture().nMonomer();
137 const int nMesh = system().domain().mesh().size();
139 int nEle = nMonomer*nMesh;
140 if (IteratorT::isFlexible_) {
141 nEle += IteratorT::nFlexibleParams();
149 template <
int D,
class T>
150 bool AmIteratorGrid<D,T>::hasInitialGuess()
151 {
return system().w().hasData(); }
156 template <
int D,
class T>
157 void AmIteratorGrid<D,T>::getCurrent(VectorT& state)
159 const int nMonomer = system().mixture().nMonomer();
160 const int nMesh = system().domain().mesh().size();
161 const int n = nElements();
166 for (
int i = 0; i < nMonomer; i++) {
167 slice.associate(state, i*nMesh, nMesh);
173 if (IteratorT::isFlexible_) {
174 int nFlex = IteratorT::nFlexibleParams();
176 UnitCell<D> const & unitCell = system().domain().unitCell();
178 const int nParam = unitCell.nParameter();
181 for (
int i = 0; i < nParam; i++) {
182 if (flexibleParams_[i]) {
183 paramsTmp[counter] = scaleStress_ * parameters[i];
191 slice.associate(state, nMonomer*nMesh, paramsTmp.capacity());
200 template <
int D,
class T>
201 void AmIteratorGrid<D,T>::evaluate()
202 { system().compute(IteratorT::isFlexible_); }
207 template <
int D,
class T>
208 void AmIteratorGrid<D,T>::getResidual(VectorT& resid)
211 const int n = nElements();
215 const RealT shift = -1.0 / interaction_.sumChiInverse();
216 const int nMonomer = system().mixture().nMonomer();
217 const int nMesh = system().domain().mesh().size();
218 const bool hasHext = system().h().hasData();
219 const bool hasMask = system().mask().hasData();
220 const bool isCanonical = system().mixture().isCanonical();
227 RealT chi, p, average;
228 for (
int i = 0; i < nMonomer; ++i) {
229 slice.associate(resid, i*nMesh, nMesh);
232 for (
int j = 0; j < nMonomer; ++j) {
233 chi = interaction_.chi(i,j);
234 p = interaction_.p(i,j);
254 average /= RealT(nMesh);
262 if (IteratorT::isFlexible_) {
273 const RealT scale = -1.0 * scaleStress_;
274 const int nParam = system().domain().unitCell().nParameter();
275 const int nFlex = IteratorT::nFlexibleParams();
279 for (
int i = 0; i < nParam ; i++) {
280 if (flexibleParams_[i]) {
281 stressTmp[counter] = scale * IteratorT::stress(i);
286 UTIL_CHECK(resid.capacity() == (nMonomer * nMesh) + nFlex);
289 VecOp::eqV(resid, stressTmp, nMonomer*nMesh, 0, nFlex);
300 template <
int D,
class T>
301 void AmIteratorGrid<D,T>::update(VectorT& newState)
304 typename T::Domain
const & domain = system().domain();
305 Mesh<D> const & mesh = domain.mesh();
306 const int nMonomer = system().mixture().nMonomer();
307 const int nMesh = mesh.
size();
312 for (
int i = 0; i < nMonomer; i++) {
313 wFields[i].
allocate(mesh.dimensions());
319 for (
int i = 0; i < nMonomer; i++) {
320 slice.associate(newState, i*nMesh, nMesh);
326 if (system().mixture().isCanonical()) {
330 for (
int i = 0; i < nMonomer; ++i) {
332 wAve /= RealT(nMesh);
339 for (
int i = 0; i < nMonomer; ++i) {
341 cAve[i] /= RealT(nMesh);
346 for (
int i = 0; i < nMonomer; ++i) {
348 for (
int j = 0; j < nMonomer; ++j) {
349 chi = interaction_.chi(i,j);
350 wAve += chi * cAve[j];
356 if (system().h().hasData()) {
358 for (
int i = 0; i < nMonomer; ++i) {
360 hAve /= RealT(nMesh);
367 system().w().setRGrid(wFields);
370 if (IteratorT::isFlexible_) {
371 const int nParam = domain.unitCell().nParameter();
372 const int nFlex = IteratorT::nFlexibleParams();
376 parameters = domain.unitCell().parameters();
380 VecOp::eqV(paramTmp, newState, 0, nMonomer*nMesh, nFlex);
387 RealT scale = 1.0 / scaleStress_;
389 for (
int i = 0; i < nParam; i++) {
390 if (flexibleParams_[i]) {
391 parameters[i] = scale * paramTmp[counter];
398 system().setUnitCell(parameters);
406 template <
int D,
class T>
407 void AmIteratorGrid<D,T>::outputToLog()
409 if (IteratorT::isFlexible_ && AmIterTmplT::verbose() > 1) {
410 UnitCell<D> const & unitCell = system().domain().unitCell();
412 const int nFlex = IteratorT::nFlexibleParams();
413 const int nMonomer = system().mixture().nMonomer();
414 const int nMesh = system().domain().mesh().size();
415 const int begin = nMonomer*nMesh;
419 VecOp::eqV(stressTmp, AmIterTmplT::residual(), 0, begin, nFlex);
423 for (
int i = 0; i < nParam; i++) {
424 if (flexibleParams_[i]) {
425 res = stressTmp[counter];
426 str = -1.0 * res / scaleStress_;
428 <<
" Cell Param " << i <<
" = "
429 <<
Dbl(unitCell.parameters()[i], 15)